1# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Keras convolution layers and image transformation layers.
16"""
17
18from __future__ import absolute_import
19from __future__ import division
20from __future__ import print_function
21
22import functools
23import six
24
25from tensorflow.python.eager import context
26from tensorflow.python.framework import tensor_shape
27from tensorflow.python.keras import activations
28from tensorflow.python.keras import backend
29from tensorflow.python.keras import constraints
30from tensorflow.python.keras import initializers
31from tensorflow.python.keras import regularizers
32from tensorflow.python.keras.engine.base_layer import Layer
33from tensorflow.python.keras.engine.input_spec import InputSpec
34# imports for backwards namespace compatibility
35# pylint: disable=unused-import
36from tensorflow.python.keras.layers.pooling import AveragePooling1D
37from tensorflow.python.keras.layers.pooling import AveragePooling2D
38from tensorflow.python.keras.layers.pooling import AveragePooling3D
39from tensorflow.python.keras.layers.pooling import MaxPooling1D
40from tensorflow.python.keras.layers.pooling import MaxPooling2D
41from tensorflow.python.keras.layers.pooling import MaxPooling3D
42# pylint: enable=unused-import
43from tensorflow.python.keras.utils import conv_utils
44from tensorflow.python.keras.utils import tf_utils
45from tensorflow.python.ops import array_ops
46from tensorflow.python.ops import nn
47from tensorflow.python.ops import nn_ops
48from tensorflow.python.util.tf_export import keras_export
49# pylint: disable=g-classes-have-attributes
50
51
52class Conv(Layer):
53  """Abstract N-D convolution layer (private, used as implementation base).
54
55  This layer creates a convolution kernel that is convolved
56  (actually cross-correlated) with the layer input to produce a tensor of
57  outputs. If `use_bias` is True (and a `bias_initializer` is provided),
58  a bias vector is created and added to the outputs. Finally, if
59  `activation` is not `None`, it is applied to the outputs as well.
60
61  Note: layer attributes cannot be modified after the layer has been called
62  once (except the `trainable` attribute).
63
64  Args:
65    rank: An integer, the rank of the convolution, e.g. "2" for 2D convolution.
66    filters: Integer, the dimensionality of the output space (i.e. the number
67      of filters in the convolution).
68    kernel_size: An integer or tuple/list of n integers, specifying the
69      length of the convolution window.
70    strides: An integer or tuple/list of n integers,
71      specifying the stride length of the convolution.
72      Specifying any stride value != 1 is incompatible with specifying
73      any `dilation_rate` value != 1.
74    padding: One of `"valid"`,  `"same"`, or `"causal"` (case-insensitive).
75      `"valid"` means no padding. `"same"` results in padding with zeros
76      evenly to the left/right or up/down of the input such that output has the
77      same height/width dimension as the input. `"causal"` results in causal
78      (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`.
79    data_format: A string, one of `channels_last` (default) or `channels_first`.
80      The ordering of the dimensions in the inputs.
81      `channels_last` corresponds to inputs with shape
82      `(batch_size, ..., channels)` while `channels_first` corresponds to
83      inputs with shape `(batch_size, channels, ...)`.
84    dilation_rate: An integer or tuple/list of n integers, specifying
85      the dilation rate to use for dilated convolution.
86      Currently, specifying any `dilation_rate` value != 1 is
87      incompatible with specifying any `strides` value != 1.
88    groups: A positive integer specifying the number of groups in which the
89      input is split along the channel axis. Each group is convolved
90      separately with `filters / groups` filters. The output is the
91      concatenation of all the `groups` results along the channel axis.
92      Input channels and `filters` must both be divisible by `groups`.
93    activation: Activation function to use.
94      If you don't specify anything, no activation is applied.
95    use_bias: Boolean, whether the layer uses a bias.
96    kernel_initializer: An initializer for the convolution kernel. If None, the
97      default initializer (glorot_uniform) will be used.
98    bias_initializer: An initializer for the bias vector. If None, the default
99      initializer (zeros) will be used.
100    kernel_regularizer: Optional regularizer for the convolution kernel.
101    bias_regularizer: Optional regularizer for the bias vector.
102    activity_regularizer: Optional regularizer function for the output.
103    kernel_constraint: Optional projection function to be applied to the
104        kernel after being updated by an `Optimizer` (e.g. used to implement
105        norm constraints or value constraints for layer weights). The function
106        must take as input the unprojected variable and must return the
107        projected variable (which must have the same shape). Constraints are
108        not safe to use when doing asynchronous distributed training.
109    bias_constraint: Optional projection function to be applied to the
110        bias after being updated by an `Optimizer`.
111  """
112
113  def __init__(self,
114               rank,
115               filters,
116               kernel_size,
117               strides=1,
118               padding='valid',
119               data_format=None,
120               dilation_rate=1,
121               groups=1,
122               activation=None,
123               use_bias=True,
124               kernel_initializer='glorot_uniform',
125               bias_initializer='zeros',
126               kernel_regularizer=None,
127               bias_regularizer=None,
128               activity_regularizer=None,
129               kernel_constraint=None,
130               bias_constraint=None,
131               trainable=True,
132               name=None,
133               conv_op=None,
134               **kwargs):
135    super(Conv, self).__init__(
136        trainable=trainable,
137        name=name,
138        activity_regularizer=regularizers.get(activity_regularizer),
139        **kwargs)
140    self.rank = rank
141
142    if isinstance(filters, float):
143      filters = int(filters)
144    self.filters = filters
145    self.groups = groups or 1
146    self.kernel_size = conv_utils.normalize_tuple(
147        kernel_size, rank, 'kernel_size')
148    self.strides = conv_utils.normalize_tuple(strides, rank, 'strides')
149    self.padding = conv_utils.normalize_padding(padding)
150    self.data_format = conv_utils.normalize_data_format(data_format)
151    self.dilation_rate = conv_utils.normalize_tuple(
152        dilation_rate, rank, 'dilation_rate')
153
154    self.activation = activations.get(activation)
155    self.use_bias = use_bias
156
157    self.kernel_initializer = initializers.get(kernel_initializer)
158    self.bias_initializer = initializers.get(bias_initializer)
159    self.kernel_regularizer = regularizers.get(kernel_regularizer)
160    self.bias_regularizer = regularizers.get(bias_regularizer)
161    self.kernel_constraint = constraints.get(kernel_constraint)
162    self.bias_constraint = constraints.get(bias_constraint)
163    self.input_spec = InputSpec(min_ndim=self.rank + 2)
164
165    self._validate_init()
166    self._is_causal = self.padding == 'causal'
167    self._channels_first = self.data_format == 'channels_first'
168    self._tf_data_format = conv_utils.convert_data_format(
169        self.data_format, self.rank + 2)
170
171  def _validate_init(self):
172    if self.filters is not None and self.filters % self.groups != 0:
173      raise ValueError(
174          'The number of filters must be evenly divisible by the number of '
175          'groups. Received: groups={}, filters={}'.format(
176              self.groups, self.filters))
177
178    if not all(self.kernel_size):
179      raise ValueError('The argument `kernel_size` cannot contain 0(s). '
180                       'Received: %s' % (self.kernel_size,))
181
182    if (self.padding == 'causal' and not isinstance(self,
183                                                    (Conv1D, SeparableConv1D))):
184      raise ValueError('Causal padding is only supported for `Conv1D`'
185                       'and `SeparableConv1D`.')
186
187  def build(self, input_shape):
188    input_shape = tensor_shape.TensorShape(input_shape)
189    input_channel = self._get_input_channel(input_shape)
190    if input_channel % self.groups != 0:
191      raise ValueError(
192          'The number of input channels must be evenly divisible by the number '
193          'of groups. Received groups={}, but the input has {} channels '
194          '(full input shape is {}).'.format(self.groups, input_channel,
195                                             input_shape))
196    kernel_shape = self.kernel_size + (input_channel // self.groups,
197                                       self.filters)
198
199    self.kernel = self.add_weight(
200        name='kernel',
201        shape=kernel_shape,
202        initializer=self.kernel_initializer,
203        regularizer=self.kernel_regularizer,
204        constraint=self.kernel_constraint,
205        trainable=True,
206        dtype=self.dtype)
207    if self.use_bias:
208      self.bias = self.add_weight(
209          name='bias',
210          shape=(self.filters,),
211          initializer=self.bias_initializer,
212          regularizer=self.bias_regularizer,
213          constraint=self.bias_constraint,
214          trainable=True,
215          dtype=self.dtype)
216    else:
217      self.bias = None
218    channel_axis = self._get_channel_axis()
219    self.input_spec = InputSpec(min_ndim=self.rank + 2,
220                                axes={channel_axis: input_channel})
221
222    # Convert Keras formats to TF native formats.
223    if self.padding == 'causal':
224      tf_padding = 'VALID'  # Causal padding handled in `call`.
225    elif isinstance(self.padding, six.string_types):
226      tf_padding = self.padding.upper()
227    else:
228      tf_padding = self.padding
229    tf_dilations = list(self.dilation_rate)
230    tf_strides = list(self.strides)
231
232    tf_op_name = self.__class__.__name__
233    if tf_op_name == 'Conv1D':
234      tf_op_name = 'conv1d'  # Backwards compat.
235
236    self._convolution_op = functools.partial(
237        nn_ops.convolution_v2,
238        strides=tf_strides,
239        padding=tf_padding,
240        dilations=tf_dilations,
241        data_format=self._tf_data_format,
242        name=tf_op_name)
243    self.built = True
244
245  def call(self, inputs):
246    input_shape = inputs.shape
247
248    if self._is_causal:  # Apply causal padding to inputs for Conv1D.
249      inputs = array_ops.pad(inputs, self._compute_causal_padding(inputs))
250
251    outputs = self._convolution_op(inputs, self.kernel)
252
253    if self.use_bias:
254      output_rank = outputs.shape.rank
255      if self.rank == 1 and self._channels_first:
256        # nn.bias_add does not accept a 1D input tensor.
257        bias = array_ops.reshape(self.bias, (1, self.filters, 1))
258        outputs += bias
259      else:
260        # Handle multiple batch dimensions.
261        if output_rank is not None and output_rank > 2 + self.rank:
262
263          def _apply_fn(o):
264            return nn.bias_add(o, self.bias, data_format=self._tf_data_format)
265
266          outputs = conv_utils.squeeze_batch_dims(
267              outputs, _apply_fn, inner_rank=self.rank + 1)
268        else:
269          outputs = nn.bias_add(
270              outputs, self.bias, data_format=self._tf_data_format)
271
272    if not context.executing_eagerly():
273      # Infer the static output shape:
274      out_shape = self.compute_output_shape(input_shape)
275      outputs.set_shape(out_shape)
276
277    if self.activation is not None:
278      return self.activation(outputs)
279    return outputs
280
281  def _spatial_output_shape(self, spatial_input_shape):
282    return [
283        conv_utils.conv_output_length(
284            length,
285            self.kernel_size[i],
286            padding=self.padding,
287            stride=self.strides[i],
288            dilation=self.dilation_rate[i])
289        for i, length in enumerate(spatial_input_shape)
290    ]
291
292  def compute_output_shape(self, input_shape):
293    input_shape = tensor_shape.TensorShape(input_shape).as_list()
294    batch_rank = len(input_shape) - self.rank - 1
295    if self.data_format == 'channels_last':
296      return tensor_shape.TensorShape(
297          input_shape[:batch_rank]
298          + self._spatial_output_shape(input_shape[batch_rank:-1])
299          + [self.filters])
300    else:
301      return tensor_shape.TensorShape(
302          input_shape[:batch_rank] + [self.filters] +
303          self._spatial_output_shape(input_shape[batch_rank + 1:]))
304
305  def _recreate_conv_op(self, inputs):  # pylint: disable=unused-argument
306    return False
307
308  def get_config(self):
309    config = {
310        'filters':
311            self.filters,
312        'kernel_size':
313            self.kernel_size,
314        'strides':
315            self.strides,
316        'padding':
317            self.padding,
318        'data_format':
319            self.data_format,
320        'dilation_rate':
321            self.dilation_rate,
322        'groups':
323            self.groups,
324        'activation':
325            activations.serialize(self.activation),
326        'use_bias':
327            self.use_bias,
328        'kernel_initializer':
329            initializers.serialize(self.kernel_initializer),
330        'bias_initializer':
331            initializers.serialize(self.bias_initializer),
332        'kernel_regularizer':
333            regularizers.serialize(self.kernel_regularizer),
334        'bias_regularizer':
335            regularizers.serialize(self.bias_regularizer),
336        'activity_regularizer':
337            regularizers.serialize(self.activity_regularizer),
338        'kernel_constraint':
339            constraints.serialize(self.kernel_constraint),
340        'bias_constraint':
341            constraints.serialize(self.bias_constraint)
342    }
343    base_config = super(Conv, self).get_config()
344    return dict(list(base_config.items()) + list(config.items()))
345
346  def _compute_causal_padding(self, inputs):
347    """Calculates padding for 'causal' option for 1-d conv layers."""
348    left_pad = self.dilation_rate[0] * (self.kernel_size[0] - 1)
349    if getattr(inputs.shape, 'ndims', None) is None:
350      batch_rank = 1
351    else:
352      batch_rank = len(inputs.shape) - 2
353    if self.data_format == 'channels_last':
354      causal_padding = [[0, 0]] * batch_rank + [[left_pad, 0], [0, 0]]
355    else:
356      causal_padding = [[0, 0]] * batch_rank + [[0, 0], [left_pad, 0]]
357    return causal_padding
358
359  def _get_channel_axis(self):
360    if self.data_format == 'channels_first':
361      return -1 - self.rank
362    else:
363      return -1
364
365  def _get_input_channel(self, input_shape):
366    channel_axis = self._get_channel_axis()
367    if input_shape.dims[channel_axis].value is None:
368      raise ValueError('The channel dimension of the inputs '
369                       'should be defined. Found `None`.')
370    return int(input_shape[channel_axis])
371
372  def _get_padding_op(self):
373    if self.padding == 'causal':
374      op_padding = 'valid'
375    else:
376      op_padding = self.padding
377    if not isinstance(op_padding, (list, tuple)):
378      op_padding = op_padding.upper()
379    return op_padding
380
381
382@keras_export('keras.layers.Conv1D', 'keras.layers.Convolution1D')
383class Conv1D(Conv):
384  """1D convolution layer (e.g. temporal convolution).
385
386  This layer creates a convolution kernel that is convolved
387  with the layer input over a single spatial (or temporal) dimension
388  to produce a tensor of outputs.
389  If `use_bias` is True, a bias vector is created and added to the outputs.
390  Finally, if `activation` is not `None`,
391  it is applied to the outputs as well.
392
393  When using this layer as the first layer in a model,
394  provide an `input_shape` argument
395  (tuple of integers or `None`, e.g.
396  `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors,
397  or `(None, 128)` for variable-length sequences of 128-dimensional vectors.
398
399  Examples:
400
401  >>> # The inputs are 128-length vectors with 10 timesteps, and the batch size
402  >>> # is 4.
403  >>> input_shape = (4, 10, 128)
404  >>> x = tf.random.normal(input_shape)
405  >>> y = tf.keras.layers.Conv1D(
406  ... 32, 3, activation='relu',input_shape=input_shape[1:])(x)
407  >>> print(y.shape)
408  (4, 8, 32)
409
410  >>> # With extended batch shape [4, 7] (e.g. weather data where batch
411  >>> # dimensions correspond to spatial location and the third dimension
412  >>> # corresponds to time.)
413  >>> input_shape = (4, 7, 10, 128)
414  >>> x = tf.random.normal(input_shape)
415  >>> y = tf.keras.layers.Conv1D(
416  ... 32, 3, activation='relu', input_shape=input_shape[2:])(x)
417  >>> print(y.shape)
418  (4, 7, 8, 32)
419
420  Args:
421    filters: Integer, the dimensionality of the output space
422      (i.e. the number of output filters in the convolution).
423    kernel_size: An integer or tuple/list of a single integer,
424      specifying the length of the 1D convolution window.
425    strides: An integer or tuple/list of a single integer,
426      specifying the stride length of the convolution.
427      Specifying any stride value != 1 is incompatible with specifying
428      any `dilation_rate` value != 1.
429    padding: One of `"valid"`, `"same"` or `"causal"` (case-insensitive).
430      `"valid"` means no padding. `"same"` results in padding with zeros evenly
431      to the left/right or up/down of the input such that output has the same
432      height/width dimension as the input.
433      `"causal"` results in causal (dilated) convolutions, e.g. `output[t]`
434      does not depend on `input[t+1:]`. Useful when modeling temporal data
435      where the model should not violate the temporal order.
436      See [WaveNet: A Generative Model for Raw Audio, section
437        2.1](https://arxiv.org/abs/1609.03499).
438    data_format: A string,
439      one of `channels_last` (default) or `channels_first`.
440    dilation_rate: an integer or tuple/list of a single integer, specifying
441      the dilation rate to use for dilated convolution.
442      Currently, specifying any `dilation_rate` value != 1 is
443      incompatible with specifying any `strides` value != 1.
444    groups: A positive integer specifying the number of groups in which the
445      input is split along the channel axis. Each group is convolved
446      separately with `filters / groups` filters. The output is the
447      concatenation of all the `groups` results along the channel axis.
448      Input channels and `filters` must both be divisible by `groups`.
449    activation: Activation function to use.
450      If you don't specify anything, no activation is applied (
451      see `keras.activations`).
452    use_bias: Boolean, whether the layer uses a bias vector.
453    kernel_initializer: Initializer for the `kernel` weights matrix (
454      see `keras.initializers`). Defaults to 'glorot_uniform'.
455    bias_initializer: Initializer for the bias vector (
456      see `keras.initializers`). Defaults to 'zeros'.
457    kernel_regularizer: Regularizer function applied to
458      the `kernel` weights matrix (see `keras.regularizers`).
459    bias_regularizer: Regularizer function applied to the bias vector (
460      see `keras.regularizers`).
461    activity_regularizer: Regularizer function applied to
462      the output of the layer (its "activation") (
463      see `keras.regularizers`).
464    kernel_constraint: Constraint function applied to the kernel matrix (
465      see `keras.constraints`).
466    bias_constraint: Constraint function applied to the bias vector (
467      see `keras.constraints`).
468
469  Input shape:
470    3+D tensor with shape: `batch_shape + (steps, input_dim)`
471
472  Output shape:
473    3+D tensor with shape: `batch_shape + (new_steps, filters)`
474      `steps` value might have changed due to padding or strides.
475
476  Returns:
477    A tensor of rank 3 representing
478    `activation(conv1d(inputs, kernel) + bias)`.
479
480  Raises:
481    ValueError: when both `strides > 1` and `dilation_rate > 1`.
482  """
483
484  def __init__(self,
485               filters,
486               kernel_size,
487               strides=1,
488               padding='valid',
489               data_format='channels_last',
490               dilation_rate=1,
491               groups=1,
492               activation=None,
493               use_bias=True,
494               kernel_initializer='glorot_uniform',
495               bias_initializer='zeros',
496               kernel_regularizer=None,
497               bias_regularizer=None,
498               activity_regularizer=None,
499               kernel_constraint=None,
500               bias_constraint=None,
501               **kwargs):
502    super(Conv1D, self).__init__(
503        rank=1,
504        filters=filters,
505        kernel_size=kernel_size,
506        strides=strides,
507        padding=padding,
508        data_format=data_format,
509        dilation_rate=dilation_rate,
510        groups=groups,
511        activation=activations.get(activation),
512        use_bias=use_bias,
513        kernel_initializer=initializers.get(kernel_initializer),
514        bias_initializer=initializers.get(bias_initializer),
515        kernel_regularizer=regularizers.get(kernel_regularizer),
516        bias_regularizer=regularizers.get(bias_regularizer),
517        activity_regularizer=regularizers.get(activity_regularizer),
518        kernel_constraint=constraints.get(kernel_constraint),
519        bias_constraint=constraints.get(bias_constraint),
520        **kwargs)
521
522
523@keras_export('keras.layers.Conv2D', 'keras.layers.Convolution2D')
524class Conv2D(Conv):
525  """2D convolution layer (e.g. spatial convolution over images).
526
527  This layer creates a convolution kernel that is convolved
528  with the layer input to produce a tensor of
529  outputs. If `use_bias` is True,
530  a bias vector is created and added to the outputs. Finally, if
531  `activation` is not `None`, it is applied to the outputs as well.
532
533  When using this layer as the first layer in a model,
534  provide the keyword argument `input_shape`
535  (tuple of integers or `None`, does not include the sample axis),
536  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
537  in `data_format="channels_last"`.
538
539  Examples:
540
541  >>> # The inputs are 28x28 RGB images with `channels_last` and the batch
542  >>> # size is 4.
543  >>> input_shape = (4, 28, 28, 3)
544  >>> x = tf.random.normal(input_shape)
545  >>> y = tf.keras.layers.Conv2D(
546  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
547  >>> print(y.shape)
548  (4, 26, 26, 2)
549
550  >>> # With `dilation_rate` as 2.
551  >>> input_shape = (4, 28, 28, 3)
552  >>> x = tf.random.normal(input_shape)
553  >>> y = tf.keras.layers.Conv2D(
554  ... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
555  >>> print(y.shape)
556  (4, 24, 24, 2)
557
558  >>> # With `padding` as "same".
559  >>> input_shape = (4, 28, 28, 3)
560  >>> x = tf.random.normal(input_shape)
561  >>> y = tf.keras.layers.Conv2D(
562  ... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
563  >>> print(y.shape)
564  (4, 28, 28, 2)
565
566  >>> # With extended batch shape [4, 7]:
567  >>> input_shape = (4, 7, 28, 28, 3)
568  >>> x = tf.random.normal(input_shape)
569  >>> y = tf.keras.layers.Conv2D(
570  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
571  >>> print(y.shape)
572  (4, 7, 26, 26, 2)
573
574
575  Args:
576    filters: Integer, the dimensionality of the output space (i.e. the number of
577      output filters in the convolution).
578    kernel_size: An integer or tuple/list of 2 integers, specifying the height
579      and width of the 2D convolution window. Can be a single integer to specify
580      the same value for all spatial dimensions.
581    strides: An integer or tuple/list of 2 integers, specifying the strides of
582      the convolution along the height and width. Can be a single integer to
583      specify the same value for all spatial dimensions. Specifying any stride
584      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
585    padding: one of `"valid"` or `"same"` (case-insensitive).
586      `"valid"` means no padding. `"same"` results in padding with zeros evenly
587      to the left/right or up/down of the input such that output has the same
588      height/width dimension as the input.
589    data_format: A string, one of `channels_last` (default) or `channels_first`.
590      The ordering of the dimensions in the inputs. `channels_last` corresponds
591      to inputs with shape `(batch_size, height, width, channels)` while
592      `channels_first` corresponds to inputs with shape `(batch_size, channels,
593      height, width)`. It defaults to the `image_data_format` value found in
594      your Keras config file at `~/.keras/keras.json`. If you never set it, then
595      it will be `channels_last`.
596    dilation_rate: an integer or tuple/list of 2 integers, specifying the
597      dilation rate to use for dilated convolution. Can be a single integer to
598      specify the same value for all spatial dimensions. Currently, specifying
599      any `dilation_rate` value != 1 is incompatible with specifying any stride
600      value != 1.
601    groups: A positive integer specifying the number of groups in which the
602      input is split along the channel axis. Each group is convolved separately
603      with `filters / groups` filters. The output is the concatenation of all
604      the `groups` results along the channel axis. Input channels and `filters`
605      must both be divisible by `groups`.
606    activation: Activation function to use. If you don't specify anything, no
607      activation is applied (see `keras.activations`).
608    use_bias: Boolean, whether the layer uses a bias vector.
609    kernel_initializer: Initializer for the `kernel` weights matrix (see
610      `keras.initializers`). Defaults to 'glorot_uniform'.
611    bias_initializer: Initializer for the bias vector (see
612      `keras.initializers`). Defaults to 'zeros'.
613    kernel_regularizer: Regularizer function applied to the `kernel` weights
614      matrix (see `keras.regularizers`).
615    bias_regularizer: Regularizer function applied to the bias vector (see
616      `keras.regularizers`).
617    activity_regularizer: Regularizer function applied to the output of the
618      layer (its "activation") (see `keras.regularizers`).
619    kernel_constraint: Constraint function applied to the kernel matrix (see
620      `keras.constraints`).
621    bias_constraint: Constraint function applied to the bias vector (see
622      `keras.constraints`).
623  Input shape:
624    4+D tensor with shape: `batch_shape + (channels, rows, cols)` if
625      `data_format='channels_first'`
626    or 4+D tensor with shape: `batch_shape + (rows, cols, channels)` if
627      `data_format='channels_last'`.
628  Output shape:
629    4+D tensor with shape: `batch_shape + (filters, new_rows, new_cols)` if
630    `data_format='channels_first'` or 4+D tensor with shape: `batch_shape +
631      (new_rows, new_cols, filters)` if `data_format='channels_last'`.  `rows`
632      and `cols` values might have changed due to padding.
633
634  Returns:
635    A tensor of rank 4+ representing
636    `activation(conv2d(inputs, kernel) + bias)`.
637
638  Raises:
639    ValueError: if `padding` is `"causal"`.
640    ValueError: when both `strides > 1` and `dilation_rate > 1`.
641  """
642
643  def __init__(self,
644               filters,
645               kernel_size,
646               strides=(1, 1),
647               padding='valid',
648               data_format=None,
649               dilation_rate=(1, 1),
650               groups=1,
651               activation=None,
652               use_bias=True,
653               kernel_initializer='glorot_uniform',
654               bias_initializer='zeros',
655               kernel_regularizer=None,
656               bias_regularizer=None,
657               activity_regularizer=None,
658               kernel_constraint=None,
659               bias_constraint=None,
660               **kwargs):
661    super(Conv2D, self).__init__(
662        rank=2,
663        filters=filters,
664        kernel_size=kernel_size,
665        strides=strides,
666        padding=padding,
667        data_format=data_format,
668        dilation_rate=dilation_rate,
669        groups=groups,
670        activation=activations.get(activation),
671        use_bias=use_bias,
672        kernel_initializer=initializers.get(kernel_initializer),
673        bias_initializer=initializers.get(bias_initializer),
674        kernel_regularizer=regularizers.get(kernel_regularizer),
675        bias_regularizer=regularizers.get(bias_regularizer),
676        activity_regularizer=regularizers.get(activity_regularizer),
677        kernel_constraint=constraints.get(kernel_constraint),
678        bias_constraint=constraints.get(bias_constraint),
679        **kwargs)
680
681
682@keras_export('keras.layers.Conv3D', 'keras.layers.Convolution3D')
683class Conv3D(Conv):
684  """3D convolution layer (e.g. spatial convolution over volumes).
685
686  This layer creates a convolution kernel that is convolved
687  with the layer input to produce a tensor of
688  outputs. If `use_bias` is True,
689  a bias vector is created and added to the outputs. Finally, if
690  `activation` is not `None`, it is applied to the outputs as well.
691
692  When using this layer as the first layer in a model,
693  provide the keyword argument `input_shape`
694  (tuple of integers or `None`, does not include the sample axis),
695  e.g. `input_shape=(128, 128, 128, 1)` for 128x128x128 volumes
696  with a single channel,
697  in `data_format="channels_last"`.
698
699  Examples:
700
701  >>> # The inputs are 28x28x28 volumes with a single channel, and the
702  >>> # batch size is 4
703  >>> input_shape =(4, 28, 28, 28, 1)
704  >>> x = tf.random.normal(input_shape)
705  >>> y = tf.keras.layers.Conv3D(
706  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
707  >>> print(y.shape)
708  (4, 26, 26, 26, 2)
709
710  >>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames,
711  >>> # with 7 frames per video.
712  >>> input_shape = (4, 7, 28, 28, 28, 1)
713  >>> x = tf.random.normal(input_shape)
714  >>> y = tf.keras.layers.Conv3D(
715  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
716  >>> print(y.shape)
717  (4, 7, 26, 26, 26, 2)
718
719  Args:
720    filters: Integer, the dimensionality of the output space (i.e. the number of
721      output filters in the convolution).
722    kernel_size: An integer or tuple/list of 3 integers, specifying the depth,
723      height and width of the 3D convolution window. Can be a single integer to
724      specify the same value for all spatial dimensions.
725    strides: An integer or tuple/list of 3 integers, specifying the strides of
726      the convolution along each spatial dimension. Can be a single integer to
727      specify the same value for all spatial dimensions. Specifying any stride
728      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
729    padding: one of `"valid"` or `"same"` (case-insensitive).
730      `"valid"` means no padding. `"same"` results in padding with zeros evenly
731      to the left/right or up/down of the input such that output has the same
732      height/width dimension as the input.
733    data_format: A string, one of `channels_last` (default) or `channels_first`.
734      The ordering of the dimensions in the inputs. `channels_last` corresponds
735      to inputs with shape `batch_shape + (spatial_dim1, spatial_dim2,
736      spatial_dim3, channels)` while `channels_first` corresponds to inputs with
737      shape `batch_shape + (channels, spatial_dim1, spatial_dim2,
738      spatial_dim3)`. It defaults to the `image_data_format` value found in your
739      Keras config file at `~/.keras/keras.json`. If you never set it, then it
740      will be "channels_last".
741    dilation_rate: an integer or tuple/list of 3 integers, specifying the
742      dilation rate to use for dilated convolution. Can be a single integer to
743      specify the same value for all spatial dimensions. Currently, specifying
744      any `dilation_rate` value != 1 is incompatible with specifying any stride
745      value != 1.
746    groups: A positive integer specifying the number of groups in which the
747      input is split along the channel axis. Each group is convolved separately
748      with `filters / groups` filters. The output is the concatenation of all
749      the `groups` results along the channel axis. Input channels and `filters`
750      must both be divisible by `groups`.
751    activation: Activation function to use. If you don't specify anything, no
752      activation is applied (see `keras.activations`).
753    use_bias: Boolean, whether the layer uses a bias vector.
754    kernel_initializer: Initializer for the `kernel` weights matrix (see
755      `keras.initializers`). Defaults to 'glorot_uniform'.
756    bias_initializer: Initializer for the bias vector (see
757      `keras.initializers`). Defaults to 'zeros'.
758    kernel_regularizer: Regularizer function applied to the `kernel` weights
759      matrix (see `keras.regularizers`).
760    bias_regularizer: Regularizer function applied to the bias vector (see
761      `keras.regularizers`).
762    activity_regularizer: Regularizer function applied to the output of the
763      layer (its "activation") (see `keras.regularizers`).
764    kernel_constraint: Constraint function applied to the kernel matrix (see
765      `keras.constraints`).
766    bias_constraint: Constraint function applied to the bias vector (see
767      `keras.constraints`).
768  Input shape:
769    5+D tensor with shape: `batch_shape + (channels, conv_dim1, conv_dim2,
770      conv_dim3)` if data_format='channels_first'
771    or 5+D tensor with shape: `batch_shape + (conv_dim1, conv_dim2, conv_dim3,
772      channels)` if data_format='channels_last'.
773  Output shape:
774    5+D tensor with shape: `batch_shape + (filters, new_conv_dim1,
775      new_conv_dim2, new_conv_dim3)` if data_format='channels_first'
776    or 5+D tensor with shape: `batch_shape + (new_conv_dim1, new_conv_dim2,
777      new_conv_dim3, filters)` if data_format='channels_last'. `new_conv_dim1`,
778      `new_conv_dim2` and `new_conv_dim3` values might have changed due to
779      padding.
780
781  Returns:
782    A tensor of rank 5+ representing
783    `activation(conv3d(inputs, kernel) + bias)`.
784
785  Raises:
786    ValueError: if `padding` is "causal".
787    ValueError: when both `strides > 1` and `dilation_rate > 1`.
788  """
789
790  def __init__(self,
791               filters,
792               kernel_size,
793               strides=(1, 1, 1),
794               padding='valid',
795               data_format=None,
796               dilation_rate=(1, 1, 1),
797               groups=1,
798               activation=None,
799               use_bias=True,
800               kernel_initializer='glorot_uniform',
801               bias_initializer='zeros',
802               kernel_regularizer=None,
803               bias_regularizer=None,
804               activity_regularizer=None,
805               kernel_constraint=None,
806               bias_constraint=None,
807               **kwargs):
808    super(Conv3D, self).__init__(
809        rank=3,
810        filters=filters,
811        kernel_size=kernel_size,
812        strides=strides,
813        padding=padding,
814        data_format=data_format,
815        dilation_rate=dilation_rate,
816        groups=groups,
817        activation=activations.get(activation),
818        use_bias=use_bias,
819        kernel_initializer=initializers.get(kernel_initializer),
820        bias_initializer=initializers.get(bias_initializer),
821        kernel_regularizer=regularizers.get(kernel_regularizer),
822        bias_regularizer=regularizers.get(bias_regularizer),
823        activity_regularizer=regularizers.get(activity_regularizer),
824        kernel_constraint=constraints.get(kernel_constraint),
825        bias_constraint=constraints.get(bias_constraint),
826        **kwargs)
827
828
829@keras_export('keras.layers.Conv1DTranspose',
830              'keras.layers.Convolution1DTranspose')
831class Conv1DTranspose(Conv1D):
832  """Transposed convolution layer (sometimes called Deconvolution).
833
834  The need for transposed convolutions generally arises
835  from the desire to use a transformation going in the opposite direction
836  of a normal convolution, i.e., from something that has the shape of the
837  output of some convolution to something that has the shape of its input
838  while maintaining a connectivity pattern that is compatible with
839  said convolution.
840
841  When using this layer as the first layer in a model,
842  provide the keyword argument `input_shape`
843  (tuple of integers or `None`, does not include the sample axis),
844  e.g. `input_shape=(128, 3)` for data with 128 time steps and 3 channels.
845
846  Args:
847    filters: Integer, the dimensionality of the output space
848      (i.e. the number of output filters in the convolution).
849    kernel_size: An integer length of the 1D convolution window.
850    strides: An integer specifying the stride of the convolution along the
851      time dimension. Specifying a stride value != 1 is incompatible with
852      specifying a `dilation_rate` value != 1. Defaults to 1.
853    padding: one of `"valid"` or `"same"` (case-insensitive).
854      `"valid"` means no padding. `"same"` results in padding with zeros evenly
855      to the left/right or up/down of the input such that output has the same
856      height/width dimension as the input.
857    output_padding: An integer specifying the amount of padding along
858      the time dimension of the output tensor.
859      The amount of output padding must be lower than the stride.
860      If set to `None` (default), the output shape is inferred.
861    data_format: A string, one of `channels_last` (default) or `channels_first`.
862      The ordering of the dimensions in the inputs.
863      `channels_last` corresponds to inputs with shape
864      `(batch_size, length, channels)` while `channels_first` corresponds to
865      inputs with shape `(batch_size, channels, length)`.
866    dilation_rate: an integer, specifying
867      the dilation rate to use for dilated convolution.
868      Currently, specifying a `dilation_rate` value != 1 is
869      incompatible with specifying a stride value != 1.
870      Also dilation rate larger than 1 is not currently supported.
871    activation: Activation function to use.
872      If you don't specify anything, no activation is applied (
873      see `keras.activations`).
874    use_bias: Boolean, whether the layer uses a bias vector.
875    kernel_initializer: Initializer for the `kernel` weights matrix (
876      see `keras.initializers`). Defaults to 'glorot_uniform'.
877    bias_initializer: Initializer for the bias vector (
878      see `keras.initializers`). Defaults to 'zeros'.
879    kernel_regularizer: Regularizer function applied to
880      the `kernel` weights matrix (see `keras.regularizers`).
881    bias_regularizer: Regularizer function applied to the bias vector (
882      see `keras.regularizers`).
883    activity_regularizer: Regularizer function applied to
884      the output of the layer (its "activation") (see `keras.regularizers`).
885    kernel_constraint: Constraint function applied to the kernel matrix (
886      see `keras.constraints`).
887    bias_constraint: Constraint function applied to the bias vector (
888      see `keras.constraints`).
889
890  Input shape:
891    3D tensor with shape:
892    `(batch_size, steps, channels)`
893
894  Output shape:
895    3D tensor with shape:
896    `(batch_size, new_steps, filters)`
897    If `output_padding` is specified:
898    ```
899    new_timesteps = ((timesteps - 1) * strides + kernel_size -
900    2 * padding + output_padding)
901    ```
902
903  Returns:
904    A tensor of rank 3 representing
905    `activation(conv1dtranspose(inputs, kernel) + bias)`.
906
907  Raises:
908    ValueError: if `padding` is "causal".
909    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
910
911  References:
912    - [A guide to convolution arithmetic for deep learning](
913      https://arxiv.org/abs/1603.07285v1)
914    - [Deconvolutional Networks](
915      https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
916  """
917
918  def __init__(self,
919               filters,
920               kernel_size,
921               strides=1,
922               padding='valid',
923               output_padding=None,
924               data_format=None,
925               dilation_rate=1,
926               activation=None,
927               use_bias=True,
928               kernel_initializer='glorot_uniform',
929               bias_initializer='zeros',
930               kernel_regularizer=None,
931               bias_regularizer=None,
932               activity_regularizer=None,
933               kernel_constraint=None,
934               bias_constraint=None,
935               **kwargs):
936    super(Conv1DTranspose, self).__init__(
937        filters=filters,
938        kernel_size=kernel_size,
939        strides=strides,
940        padding=padding,
941        data_format=data_format,
942        dilation_rate=dilation_rate,
943        activation=activations.get(activation),
944        use_bias=use_bias,
945        kernel_initializer=initializers.get(kernel_initializer),
946        bias_initializer=initializers.get(bias_initializer),
947        kernel_regularizer=regularizers.get(kernel_regularizer),
948        bias_regularizer=regularizers.get(bias_regularizer),
949        activity_regularizer=regularizers.get(activity_regularizer),
950        kernel_constraint=constraints.get(kernel_constraint),
951        bias_constraint=constraints.get(bias_constraint),
952        **kwargs)
953
954    self.output_padding = output_padding
955    if self.output_padding is not None:
956      self.output_padding = conv_utils.normalize_tuple(
957          self.output_padding, 1, 'output_padding')
958      for stride, out_pad in zip(self.strides, self.output_padding):
959        if out_pad >= stride:
960          raise ValueError('Stride ' + str(self.strides) + ' must be '
961                           'greater than output padding ' +
962                           str(self.output_padding))
963
964  def build(self, input_shape):
965    input_shape = tensor_shape.TensorShape(input_shape)
966    if len(input_shape) != 3:
967      raise ValueError('Inputs should have rank 3. Received input shape: ' +
968                       str(input_shape))
969    channel_axis = self._get_channel_axis()
970    if input_shape.dims[channel_axis].value is None:
971      raise ValueError('The channel dimension of the inputs '
972                       'should be defined. Found `None`.')
973    input_dim = int(input_shape[channel_axis])
974    self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim})
975    kernel_shape = self.kernel_size + (self.filters, input_dim)
976
977    self.kernel = self.add_weight(
978        name='kernel',
979        shape=kernel_shape,
980        initializer=self.kernel_initializer,
981        regularizer=self.kernel_regularizer,
982        constraint=self.kernel_constraint,
983        trainable=True,
984        dtype=self.dtype)
985    if self.use_bias:
986      self.bias = self.add_weight(
987          name='bias',
988          shape=(self.filters,),
989          initializer=self.bias_initializer,
990          regularizer=self.bias_regularizer,
991          constraint=self.bias_constraint,
992          trainable=True,
993          dtype=self.dtype)
994    else:
995      self.bias = None
996    self.built = True
997
998  def call(self, inputs):
999    inputs_shape = array_ops.shape(inputs)
1000    batch_size = inputs_shape[0]
1001    if self.data_format == 'channels_first':
1002      t_axis = 2
1003    else:
1004      t_axis = 1
1005
1006    length = inputs_shape[t_axis]
1007    if self.output_padding is None:
1008      output_padding = None
1009    else:
1010      output_padding = self.output_padding[0]
1011
1012    # Infer the dynamic output shape:
1013    out_length = conv_utils.deconv_output_length(
1014        length, self.kernel_size[0], padding=self.padding,
1015        output_padding=output_padding, stride=self.strides[0],
1016        dilation=self.dilation_rate[0])
1017    if self.data_format == 'channels_first':
1018      output_shape = (batch_size, self.filters, out_length)
1019    else:
1020      output_shape = (batch_size, out_length, self.filters)
1021    data_format = conv_utils.convert_data_format(self.data_format, ndim=3)
1022
1023    output_shape_tensor = array_ops.stack(output_shape)
1024    outputs = nn_ops.conv1d_transpose(
1025        inputs,
1026        self.kernel,
1027        output_shape_tensor,
1028        strides=self.strides,
1029        padding=self.padding.upper(),
1030        data_format=data_format,
1031        dilations=self.dilation_rate)
1032
1033    if not context.executing_eagerly():
1034      # Infer the static output shape:
1035      out_shape = self.compute_output_shape(inputs.shape)
1036      outputs.set_shape(out_shape)
1037
1038    if self.use_bias:
1039      outputs = nn.bias_add(
1040          outputs,
1041          self.bias,
1042          data_format=data_format)
1043
1044    if self.activation is not None:
1045      return self.activation(outputs)
1046    return outputs
1047
1048  def compute_output_shape(self, input_shape):
1049    input_shape = tensor_shape.TensorShape(input_shape).as_list()
1050    output_shape = list(input_shape)
1051    if self.data_format == 'channels_first':
1052      c_axis, t_axis = 1, 2
1053    else:
1054      c_axis, t_axis = 2, 1
1055
1056    if self.output_padding is None:
1057      output_padding = None
1058    else:
1059      output_padding = self.output_padding[0]
1060    output_shape[c_axis] = self.filters
1061    output_shape[t_axis] = conv_utils.deconv_output_length(
1062        output_shape[t_axis],
1063        self.kernel_size[0],
1064        padding=self.padding,
1065        output_padding=output_padding,
1066        stride=self.strides[0],
1067        dilation=self.dilation_rate[0])
1068    return tensor_shape.TensorShape(output_shape)
1069
1070  def get_config(self):
1071    config = super(Conv1DTranspose, self).get_config()
1072    config['output_padding'] = self.output_padding
1073    return config
1074
1075
1076@keras_export('keras.layers.Conv2DTranspose',
1077              'keras.layers.Convolution2DTranspose')
1078class Conv2DTranspose(Conv2D):
1079  """Transposed convolution layer (sometimes called Deconvolution).
1080
1081  The need for transposed convolutions generally arises
1082  from the desire to use a transformation going in the opposite direction
1083  of a normal convolution, i.e., from something that has the shape of the
1084  output of some convolution to something that has the shape of its input
1085  while maintaining a connectivity pattern that is compatible with
1086  said convolution.
1087
1088  When using this layer as the first layer in a model,
1089  provide the keyword argument `input_shape`
1090  (tuple of integers or `None`, does not include the sample axis),
1091  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
1092  in `data_format="channels_last"`.
1093
1094  Args:
1095    filters: Integer, the dimensionality of the output space
1096      (i.e. the number of output filters in the convolution).
1097    kernel_size: An integer or tuple/list of 2 integers, specifying the
1098      height and width of the 2D convolution window.
1099      Can be a single integer to specify the same value for
1100      all spatial dimensions.
1101    strides: An integer or tuple/list of 2 integers,
1102      specifying the strides of the convolution along the height and width.
1103      Can be a single integer to specify the same value for
1104      all spatial dimensions.
1105      Specifying any stride value != 1 is incompatible with specifying
1106      any `dilation_rate` value != 1.
1107    padding: one of `"valid"` or `"same"` (case-insensitive).
1108      `"valid"` means no padding. `"same"` results in padding with zeros evenly
1109      to the left/right or up/down of the input such that output has the same
1110      height/width dimension as the input.
1111    output_padding: An integer or tuple/list of 2 integers,
1112      specifying the amount of padding along the height and width
1113      of the output tensor.
1114      Can be a single integer to specify the same value for all
1115      spatial dimensions.
1116      The amount of output padding along a given dimension must be
1117      lower than the stride along that same dimension.
1118      If set to `None` (default), the output shape is inferred.
1119    data_format: A string,
1120      one of `channels_last` (default) or `channels_first`.
1121      The ordering of the dimensions in the inputs.
1122      `channels_last` corresponds to inputs with shape
1123      `(batch_size, height, width, channels)` while `channels_first`
1124      corresponds to inputs with shape
1125      `(batch_size, channels, height, width)`.
1126      It defaults to the `image_data_format` value found in your
1127      Keras config file at `~/.keras/keras.json`.
1128      If you never set it, then it will be "channels_last".
1129    dilation_rate: an integer or tuple/list of 2 integers, specifying
1130      the dilation rate to use for dilated convolution.
1131      Can be a single integer to specify the same value for
1132      all spatial dimensions.
1133      Currently, specifying any `dilation_rate` value != 1 is
1134      incompatible with specifying any stride value != 1.
1135    activation: Activation function to use.
1136      If you don't specify anything, no activation is applied (
1137      see `keras.activations`).
1138    use_bias: Boolean, whether the layer uses a bias vector.
1139    kernel_initializer: Initializer for the `kernel` weights matrix (
1140      see `keras.initializers`). Defaults to 'glorot_uniform'.
1141    bias_initializer: Initializer for the bias vector (
1142      see `keras.initializers`). Defaults to 'zeros'.
1143    kernel_regularizer: Regularizer function applied to
1144      the `kernel` weights matrix (see `keras.regularizers`).
1145    bias_regularizer: Regularizer function applied to the bias vector (
1146      see `keras.regularizers`).
1147    activity_regularizer: Regularizer function applied to
1148      the output of the layer (its "activation") (see `keras.regularizers`).
1149    kernel_constraint: Constraint function applied to the kernel matrix (
1150      see `keras.constraints`).
1151    bias_constraint: Constraint function applied to the bias vector (
1152      see `keras.constraints`).
1153
1154  Input shape:
1155    4D tensor with shape:
1156    `(batch_size, channels, rows, cols)` if data_format='channels_first'
1157    or 4D tensor with shape:
1158    `(batch_size, rows, cols, channels)` if data_format='channels_last'.
1159
1160  Output shape:
1161    4D tensor with shape:
1162    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
1163    or 4D tensor with shape:
1164    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
1165    `rows` and `cols` values might have changed due to padding.
1166    If `output_padding` is specified:
1167    ```
1168    new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
1169    output_padding[0])
1170    new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
1171    output_padding[1])
1172    ```
1173
1174  Returns:
1175    A tensor of rank 4 representing
1176    `activation(conv2dtranspose(inputs, kernel) + bias)`.
1177
1178  Raises:
1179    ValueError: if `padding` is "causal".
1180    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
1181
1182  References:
1183    - [A guide to convolution arithmetic for deep
1184      learning](https://arxiv.org/abs/1603.07285v1)
1185    - [Deconvolutional
1186      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
1187  """
1188
1189  def __init__(self,
1190               filters,
1191               kernel_size,
1192               strides=(1, 1),
1193               padding='valid',
1194               output_padding=None,
1195               data_format=None,
1196               dilation_rate=(1, 1),
1197               activation=None,
1198               use_bias=True,
1199               kernel_initializer='glorot_uniform',
1200               bias_initializer='zeros',
1201               kernel_regularizer=None,
1202               bias_regularizer=None,
1203               activity_regularizer=None,
1204               kernel_constraint=None,
1205               bias_constraint=None,
1206               **kwargs):
1207    super(Conv2DTranspose, self).__init__(
1208        filters=filters,
1209        kernel_size=kernel_size,
1210        strides=strides,
1211        padding=padding,
1212        data_format=data_format,
1213        dilation_rate=dilation_rate,
1214        activation=activations.get(activation),
1215        use_bias=use_bias,
1216        kernel_initializer=initializers.get(kernel_initializer),
1217        bias_initializer=initializers.get(bias_initializer),
1218        kernel_regularizer=regularizers.get(kernel_regularizer),
1219        bias_regularizer=regularizers.get(bias_regularizer),
1220        activity_regularizer=regularizers.get(activity_regularizer),
1221        kernel_constraint=constraints.get(kernel_constraint),
1222        bias_constraint=constraints.get(bias_constraint),
1223        **kwargs)
1224
1225    self.output_padding = output_padding
1226    if self.output_padding is not None:
1227      self.output_padding = conv_utils.normalize_tuple(
1228          self.output_padding, 2, 'output_padding')
1229      for stride, out_pad in zip(self.strides, self.output_padding):
1230        if out_pad >= stride:
1231          raise ValueError('Stride ' + str(self.strides) + ' must be '
1232                           'greater than output padding ' +
1233                           str(self.output_padding))
1234
1235  def build(self, input_shape):
1236    input_shape = tensor_shape.TensorShape(input_shape)
1237    if len(input_shape) != 4:
1238      raise ValueError('Inputs should have rank 4. Received input '
1239                       'shape: ' + str(input_shape))
1240    channel_axis = self._get_channel_axis()
1241    if input_shape.dims[channel_axis].value is None:
1242      raise ValueError('The channel dimension of the inputs '
1243                       'should be defined. Found `None`.')
1244    input_dim = int(input_shape[channel_axis])
1245    self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
1246    kernel_shape = self.kernel_size + (self.filters, input_dim)
1247
1248    self.kernel = self.add_weight(
1249        name='kernel',
1250        shape=kernel_shape,
1251        initializer=self.kernel_initializer,
1252        regularizer=self.kernel_regularizer,
1253        constraint=self.kernel_constraint,
1254        trainable=True,
1255        dtype=self.dtype)
1256    if self.use_bias:
1257      self.bias = self.add_weight(
1258          name='bias',
1259          shape=(self.filters,),
1260          initializer=self.bias_initializer,
1261          regularizer=self.bias_regularizer,
1262          constraint=self.bias_constraint,
1263          trainable=True,
1264          dtype=self.dtype)
1265    else:
1266      self.bias = None
1267    self.built = True
1268
1269  def call(self, inputs):
1270    inputs_shape = array_ops.shape(inputs)
1271    batch_size = inputs_shape[0]
1272    if self.data_format == 'channels_first':
1273      h_axis, w_axis = 2, 3
1274    else:
1275      h_axis, w_axis = 1, 2
1276
1277    # Use the constant height and weight when possible.
1278    # TODO(scottzhu): Extract this into a utility function that can be applied
1279    # to all convolutional layers, which currently lost the static shape
1280    # information due to tf.shape().
1281    height, width = None, None
1282    if inputs.shape.rank is not None:
1283      dims = inputs.shape.as_list()
1284      height = dims[h_axis]
1285      width = dims[w_axis]
1286    height = height if height is not None else inputs_shape[h_axis]
1287    width = width if width is not None else inputs_shape[w_axis]
1288
1289    kernel_h, kernel_w = self.kernel_size
1290    stride_h, stride_w = self.strides
1291
1292    if self.output_padding is None:
1293      out_pad_h = out_pad_w = None
1294    else:
1295      out_pad_h, out_pad_w = self.output_padding
1296
1297    # Infer the dynamic output shape:
1298    out_height = conv_utils.deconv_output_length(height,
1299                                                 kernel_h,
1300                                                 padding=self.padding,
1301                                                 output_padding=out_pad_h,
1302                                                 stride=stride_h,
1303                                                 dilation=self.dilation_rate[0])
1304    out_width = conv_utils.deconv_output_length(width,
1305                                                kernel_w,
1306                                                padding=self.padding,
1307                                                output_padding=out_pad_w,
1308                                                stride=stride_w,
1309                                                dilation=self.dilation_rate[1])
1310    if self.data_format == 'channels_first':
1311      output_shape = (batch_size, self.filters, out_height, out_width)
1312    else:
1313      output_shape = (batch_size, out_height, out_width, self.filters)
1314
1315    output_shape_tensor = array_ops.stack(output_shape)
1316    outputs = backend.conv2d_transpose(
1317        inputs,
1318        self.kernel,
1319        output_shape_tensor,
1320        strides=self.strides,
1321        padding=self.padding,
1322        data_format=self.data_format,
1323        dilation_rate=self.dilation_rate)
1324
1325    if not context.executing_eagerly():
1326      # Infer the static output shape:
1327      out_shape = self.compute_output_shape(inputs.shape)
1328      outputs.set_shape(out_shape)
1329
1330    if self.use_bias:
1331      outputs = nn.bias_add(
1332          outputs,
1333          self.bias,
1334          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
1335
1336    if self.activation is not None:
1337      return self.activation(outputs)
1338    return outputs
1339
1340  def compute_output_shape(self, input_shape):
1341    input_shape = tensor_shape.TensorShape(input_shape).as_list()
1342    output_shape = list(input_shape)
1343    if self.data_format == 'channels_first':
1344      c_axis, h_axis, w_axis = 1, 2, 3
1345    else:
1346      c_axis, h_axis, w_axis = 3, 1, 2
1347
1348    kernel_h, kernel_w = self.kernel_size
1349    stride_h, stride_w = self.strides
1350
1351    if self.output_padding is None:
1352      out_pad_h = out_pad_w = None
1353    else:
1354      out_pad_h, out_pad_w = self.output_padding
1355
1356    output_shape[c_axis] = self.filters
1357    output_shape[h_axis] = conv_utils.deconv_output_length(
1358        output_shape[h_axis],
1359        kernel_h,
1360        padding=self.padding,
1361        output_padding=out_pad_h,
1362        stride=stride_h,
1363        dilation=self.dilation_rate[0])
1364    output_shape[w_axis] = conv_utils.deconv_output_length(
1365        output_shape[w_axis],
1366        kernel_w,
1367        padding=self.padding,
1368        output_padding=out_pad_w,
1369        stride=stride_w,
1370        dilation=self.dilation_rate[1])
1371    return tensor_shape.TensorShape(output_shape)
1372
1373  def get_config(self):
1374    config = super(Conv2DTranspose, self).get_config()
1375    config['output_padding'] = self.output_padding
1376    return config
1377
1378
1379@keras_export('keras.layers.Conv3DTranspose',
1380              'keras.layers.Convolution3DTranspose')
1381class Conv3DTranspose(Conv3D):
1382  """Transposed convolution layer (sometimes called Deconvolution).
1383
1384  The need for transposed convolutions generally arises
1385  from the desire to use a transformation going in the opposite direction
1386  of a normal convolution, i.e., from something that has the shape of the
1387  output of some convolution to something that has the shape of its input
1388  while maintaining a connectivity pattern that is compatible with
1389  said convolution.
1390
1391  When using this layer as the first layer in a model,
1392  provide the keyword argument `input_shape`
1393  (tuple of integers or `None`, does not include the sample axis),
1394  e.g. `input_shape=(128, 128, 128, 3)` for a 128x128x128 volume with 3 channels
1395  if `data_format="channels_last"`.
1396
1397  Args:
1398    filters: Integer, the dimensionality of the output space
1399      (i.e. the number of output filters in the convolution).
1400    kernel_size: An integer or tuple/list of 3 integers, specifying the
1401      depth, height and width of the 3D convolution window.
1402      Can be a single integer to specify the same value for
1403      all spatial dimensions.
1404    strides: An integer or tuple/list of 3 integers,
1405      specifying the strides of the convolution along the depth, height
1406        and width.
1407      Can be a single integer to specify the same value for
1408      all spatial dimensions.
1409      Specifying any stride value != 1 is incompatible with specifying
1410      any `dilation_rate` value != 1.
1411    padding: one of `"valid"` or `"same"` (case-insensitive).
1412      `"valid"` means no padding. `"same"` results in padding with zeros evenly
1413      to the left/right or up/down of the input such that output has the same
1414      height/width dimension as the input.
1415    output_padding: An integer or tuple/list of 3 integers,
1416      specifying the amount of padding along the depth, height, and
1417      width.
1418      Can be a single integer to specify the same value for all
1419      spatial dimensions.
1420      The amount of output padding along a given dimension must be
1421      lower than the stride along that same dimension.
1422      If set to `None` (default), the output shape is inferred.
1423    data_format: A string,
1424      one of `channels_last` (default) or `channels_first`.
1425      The ordering of the dimensions in the inputs.
1426      `channels_last` corresponds to inputs with shape
1427      `(batch_size, depth, height, width, channels)` while `channels_first`
1428      corresponds to inputs with shape
1429      `(batch_size, channels, depth, height, width)`.
1430      It defaults to the `image_data_format` value found in your
1431      Keras config file at `~/.keras/keras.json`.
1432      If you never set it, then it will be "channels_last".
1433    dilation_rate: an integer or tuple/list of 3 integers, specifying
1434      the dilation rate to use for dilated convolution.
1435      Can be a single integer to specify the same value for
1436      all spatial dimensions.
1437      Currently, specifying any `dilation_rate` value != 1 is
1438      incompatible with specifying any stride value != 1.
1439    activation: Activation function to use.
1440      If you don't specify anything, no activation is applied (
1441      see `keras.activations`).
1442    use_bias: Boolean, whether the layer uses a bias vector.
1443    kernel_initializer: Initializer for the `kernel` weights matrix (
1444      see `keras.initializers`). Defaults to 'glorot_uniform'.
1445    bias_initializer: Initializer for the bias vector (
1446      see `keras.initializers`). Defaults to 'zeros'.
1447    kernel_regularizer: Regularizer function applied to
1448      the `kernel` weights matrix (
1449      see `keras.regularizers`).
1450    bias_regularizer: Regularizer function applied to the bias vector (
1451      see `keras.regularizers`).
1452    activity_regularizer: Regularizer function applied to
1453      the output of the layer (its "activation") (
1454      see `keras.regularizers`).
1455    kernel_constraint: Constraint function applied to the kernel matrix (
1456      see `keras.constraints`).
1457    bias_constraint: Constraint function applied to the bias vector (
1458      see `keras.constraints`).
1459
1460  Input shape:
1461    5D tensor with shape:
1462    `(batch_size, channels, depth, rows, cols)` if data_format='channels_first'
1463    or 5D tensor with shape:
1464    `(batch_size, depth, rows, cols, channels)` if data_format='channels_last'.
1465
1466  Output shape:
1467    5D tensor with shape:
1468    `(batch_size, filters, new_depth, new_rows, new_cols)` if
1469      data_format='channels_first'
1470    or 5D tensor with shape:
1471    `(batch_size, new_depth, new_rows, new_cols, filters)` if
1472      data_format='channels_last'.
1473    `depth` and `rows` and `cols` values might have changed due to padding.
1474    If `output_padding` is specified::
1475    ```
1476    new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
1477    output_padding[0])
1478    new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
1479    output_padding[1])
1480    new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] +
1481    output_padding[2])
1482    ```
1483
1484  Returns:
1485    A tensor of rank 5 representing
1486    `activation(conv3dtranspose(inputs, kernel) + bias)`.
1487
1488  Raises:
1489    ValueError: if `padding` is "causal".
1490    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
1491
1492  References:
1493    - [A guide to convolution arithmetic for deep
1494      learning](https://arxiv.org/abs/1603.07285v1)
1495    - [Deconvolutional
1496      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
1497  """
1498
1499  def __init__(self,
1500               filters,
1501               kernel_size,
1502               strides=(1, 1, 1),
1503               padding='valid',
1504               output_padding=None,
1505               data_format=None,
1506               dilation_rate=(1, 1, 1),
1507               activation=None,
1508               use_bias=True,
1509               kernel_initializer='glorot_uniform',
1510               bias_initializer='zeros',
1511               kernel_regularizer=None,
1512               bias_regularizer=None,
1513               activity_regularizer=None,
1514               kernel_constraint=None,
1515               bias_constraint=None,
1516               **kwargs):
1517    super(Conv3DTranspose, self).__init__(
1518        filters=filters,
1519        kernel_size=kernel_size,
1520        strides=strides,
1521        padding=padding,
1522        data_format=data_format,
1523        dilation_rate=dilation_rate,
1524        activation=activations.get(activation),
1525        use_bias=use_bias,
1526        kernel_initializer=initializers.get(kernel_initializer),
1527        bias_initializer=initializers.get(bias_initializer),
1528        kernel_regularizer=regularizers.get(kernel_regularizer),
1529        bias_regularizer=regularizers.get(bias_regularizer),
1530        activity_regularizer=regularizers.get(activity_regularizer),
1531        kernel_constraint=constraints.get(kernel_constraint),
1532        bias_constraint=constraints.get(bias_constraint),
1533        **kwargs)
1534
1535    self.output_padding = output_padding
1536    if self.output_padding is not None:
1537      self.output_padding = conv_utils.normalize_tuple(
1538          self.output_padding, 3, 'output_padding')
1539      for stride, out_pad in zip(self.strides, self.output_padding):
1540        if out_pad >= stride:
1541          raise ValueError('Stride ' + str(self.strides) + ' must be '
1542                           'greater than output padding ' +
1543                           str(self.output_padding))
1544
1545  def build(self, input_shape):
1546    input_shape = tensor_shape.TensorShape(input_shape)
1547    if len(input_shape) != 5:
1548      raise ValueError('Inputs should have rank 5, received input shape:',
1549                       str(input_shape))
1550    channel_axis = self._get_channel_axis()
1551    if input_shape.dims[channel_axis].value is None:
1552      raise ValueError('The channel dimension of the inputs '
1553                       'should be defined, found None: ' + str(input_shape))
1554    input_dim = int(input_shape[channel_axis])
1555    kernel_shape = self.kernel_size + (self.filters, input_dim)
1556    self.input_spec = InputSpec(ndim=5, axes={channel_axis: input_dim})
1557
1558    self.kernel = self.add_weight(
1559        'kernel',
1560        shape=kernel_shape,
1561        initializer=self.kernel_initializer,
1562        regularizer=self.kernel_regularizer,
1563        constraint=self.kernel_constraint,
1564        trainable=True,
1565        dtype=self.dtype)
1566    if self.use_bias:
1567      self.bias = self.add_weight(
1568          'bias',
1569          shape=(self.filters,),
1570          initializer=self.bias_initializer,
1571          regularizer=self.bias_regularizer,
1572          constraint=self.bias_constraint,
1573          trainable=True,
1574          dtype=self.dtype)
1575    else:
1576      self.bias = None
1577    self.built = True
1578
1579  def call(self, inputs):
1580    inputs_shape = array_ops.shape(inputs)
1581    batch_size = inputs_shape[0]
1582    if self.data_format == 'channels_first':
1583      d_axis, h_axis, w_axis = 2, 3, 4
1584    else:
1585      d_axis, h_axis, w_axis = 1, 2, 3
1586
1587    depth = inputs_shape[d_axis]
1588    height = inputs_shape[h_axis]
1589    width = inputs_shape[w_axis]
1590
1591    kernel_d, kernel_h, kernel_w = self.kernel_size
1592    stride_d, stride_h, stride_w = self.strides
1593
1594    if self.output_padding is None:
1595      out_pad_d = out_pad_h = out_pad_w = None
1596    else:
1597      out_pad_d, out_pad_h, out_pad_w = self.output_padding
1598
1599    # Infer the dynamic output shape:
1600    out_depth = conv_utils.deconv_output_length(depth,
1601                                                kernel_d,
1602                                                padding=self.padding,
1603                                                output_padding=out_pad_d,
1604                                                stride=stride_d)
1605    out_height = conv_utils.deconv_output_length(height,
1606                                                 kernel_h,
1607                                                 padding=self.padding,
1608                                                 output_padding=out_pad_h,
1609                                                 stride=stride_h)
1610    out_width = conv_utils.deconv_output_length(width,
1611                                                kernel_w,
1612                                                padding=self.padding,
1613                                                output_padding=out_pad_w,
1614                                                stride=stride_w)
1615    if self.data_format == 'channels_first':
1616      output_shape = (batch_size, self.filters, out_depth, out_height,
1617                      out_width)
1618      strides = (1, 1, stride_d, stride_h, stride_w)
1619    else:
1620      output_shape = (batch_size, out_depth, out_height, out_width,
1621                      self.filters)
1622      strides = (1, stride_d, stride_h, stride_w, 1)
1623
1624    output_shape_tensor = array_ops.stack(output_shape)
1625    outputs = nn.conv3d_transpose(
1626        inputs,
1627        self.kernel,
1628        output_shape_tensor,
1629        strides,
1630        data_format=conv_utils.convert_data_format(self.data_format, ndim=5),
1631        padding=self.padding.upper())
1632
1633    if not context.executing_eagerly():
1634      # Infer the static output shape:
1635      out_shape = self.compute_output_shape(inputs.shape)
1636      outputs.set_shape(out_shape)
1637
1638    if self.use_bias:
1639      outputs = nn.bias_add(
1640          outputs,
1641          self.bias,
1642          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
1643
1644    if self.activation is not None:
1645      return self.activation(outputs)
1646    return outputs
1647
1648  def compute_output_shape(self, input_shape):
1649    input_shape = tensor_shape.TensorShape(input_shape).as_list()
1650    output_shape = list(input_shape)
1651    if self.data_format == 'channels_first':
1652      c_axis, d_axis, h_axis, w_axis = 1, 2, 3, 4
1653    else:
1654      c_axis, d_axis, h_axis, w_axis = 4, 1, 2, 3
1655
1656    kernel_d, kernel_h, kernel_w = self.kernel_size
1657    stride_d, stride_h, stride_w = self.strides
1658
1659    if self.output_padding is None:
1660      out_pad_d = out_pad_h = out_pad_w = None
1661    else:
1662      out_pad_d, out_pad_h, out_pad_w = self.output_padding
1663
1664    output_shape[c_axis] = self.filters
1665    output_shape[d_axis] = conv_utils.deconv_output_length(
1666        output_shape[d_axis],
1667        kernel_d,
1668        padding=self.padding,
1669        output_padding=out_pad_d,
1670        stride=stride_d)
1671    output_shape[h_axis] = conv_utils.deconv_output_length(
1672        output_shape[h_axis],
1673        kernel_h,
1674        padding=self.padding,
1675        output_padding=out_pad_h,
1676        stride=stride_h)
1677    output_shape[w_axis] = conv_utils.deconv_output_length(
1678        output_shape[w_axis],
1679        kernel_w,
1680        padding=self.padding,
1681        output_padding=out_pad_w,
1682        stride=stride_w)
1683    return tensor_shape.TensorShape(output_shape)
1684
1685  def get_config(self):
1686    config = super(Conv3DTranspose, self).get_config()
1687    config.pop('dilation_rate')
1688    config['output_padding'] = self.output_padding
1689    return config
1690
1691
1692class SeparableConv(Conv):
1693  """Abstract base layer for separable nD convolution.
1694
1695  This layer performs a depthwise convolution that acts separately on
1696  channels, followed by a pointwise convolution that mixes channels.
1697  If `use_bias` is True and a bias initializer is provided,
1698  it adds a bias vector to the output.
1699  It then optionally applies an activation function to produce the final output.
1700
1701  Args:
1702    rank: An integer, the rank of the convolution, e.g. "2" for 2D convolution.
1703    filters: Integer, the dimensionality of the output space (i.e. the number
1704      of filters in the convolution).
1705    kernel_size: A tuple or list of integers specifying the spatial
1706      dimensions of the filters. Can be a single integer to specify the same
1707      value for all spatial dimensions.
1708    strides: A tuple or list of integers specifying the strides
1709      of the convolution. Can be a single integer to specify the same value for
1710      all spatial dimensions.
1711      Specifying any `stride` value != 1 is incompatible with specifying
1712      any `dilation_rate` value != 1.
1713    padding: One of `"valid"` or `"same"` (case-insensitive).
1714      `"valid"` means no padding. `"same"` results in padding with zeros evenly
1715      to the left/right or up/down of the input such that output has the same
1716      height/width dimension as the input.
1717    data_format: A string, one of `channels_last` (default) or `channels_first`.
1718      The ordering of the dimensions in the inputs.
1719      `channels_last` corresponds to inputs with shape
1720      `(batch_size, ..., channels)` while `channels_first` corresponds to
1721      inputs with shape `(batch_size, channels, ...)`.
1722    dilation_rate: An integer or tuple/list of 2 integers, specifying
1723      the dilation rate to use for dilated convolution.
1724      Can be a single integer to specify the same value for
1725      all spatial dimensions.
1726      Currently, specifying any `dilation_rate` value != 1 is
1727      incompatible with specifying any stride value != 1.
1728    depth_multiplier: The number of depthwise convolution output channels for
1729      each input channel. The total number of depthwise convolution output
1730      channels will be equal to `num_filters_in * depth_multiplier`.
1731    activation: Activation function to use.
1732      If you don't specify anything, no activation is applied (
1733      see `keras.activations`).
1734    use_bias: Boolean, whether the layer uses a bias.
1735    depthwise_initializer: An initializer for the depthwise convolution kernel (
1736      see `keras.initializers`). If None, then the default initializer (
1737      'glorot_uniform') will be used.
1738    pointwise_initializer: An initializer for the pointwise convolution kernel (
1739      see `keras.initializers`). If None, then the default initializer
1740      ('glorot_uniform') will be used.
1741    bias_initializer: An initializer for the bias vector. If None, the default
1742      initializer ('zeros') will be used (see `keras.initializers`).
1743    depthwise_regularizer: Optional regularizer for the depthwise
1744      convolution kernel.
1745    pointwise_regularizer: Optional regularizer for the pointwise
1746      convolution kernel.
1747    bias_regularizer: Optional regularizer for the bias vector.
1748    activity_regularizer: Optional regularizer function for the output.
1749    depthwise_constraint: Optional projection function to be applied to the
1750      depthwise kernel after being updated by an `Optimizer` (e.g. used for
1751      norm constraints or value constraints for layer weights). The function
1752      must take as input the unprojected variable and must return the
1753      projected variable (which must have the same shape). Constraints are
1754      not safe to use when doing asynchronous distributed training.
1755    pointwise_constraint: Optional projection function to be applied to the
1756      pointwise kernel after being updated by an `Optimizer`.
1757    bias_constraint: Optional projection function to be applied to the
1758      bias after being updated by an `Optimizer`.
1759    trainable: Boolean, if `True` the weights of this layer will be marked as
1760      trainable (and listed in `layer.trainable_weights`).
1761  """
1762
1763  def __init__(self,
1764               rank,
1765               filters,
1766               kernel_size,
1767               strides=1,
1768               padding='valid',
1769               data_format=None,
1770               dilation_rate=1,
1771               depth_multiplier=1,
1772               activation=None,
1773               use_bias=True,
1774               depthwise_initializer='glorot_uniform',
1775               pointwise_initializer='glorot_uniform',
1776               bias_initializer='zeros',
1777               depthwise_regularizer=None,
1778               pointwise_regularizer=None,
1779               bias_regularizer=None,
1780               activity_regularizer=None,
1781               depthwise_constraint=None,
1782               pointwise_constraint=None,
1783               bias_constraint=None,
1784               trainable=True,
1785               name=None,
1786               **kwargs):
1787    super(SeparableConv, self).__init__(
1788        rank=rank,
1789        filters=filters,
1790        kernel_size=kernel_size,
1791        strides=strides,
1792        padding=padding,
1793        data_format=data_format,
1794        dilation_rate=dilation_rate,
1795        activation=activations.get(activation),
1796        use_bias=use_bias,
1797        bias_initializer=initializers.get(bias_initializer),
1798        bias_regularizer=regularizers.get(bias_regularizer),
1799        activity_regularizer=regularizers.get(activity_regularizer),
1800        bias_constraint=bias_constraint,
1801        trainable=trainable,
1802        name=name,
1803        **kwargs)
1804    self.depth_multiplier = depth_multiplier
1805    self.depthwise_initializer = initializers.get(depthwise_initializer)
1806    self.pointwise_initializer = initializers.get(pointwise_initializer)
1807    self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
1808    self.pointwise_regularizer = regularizers.get(pointwise_regularizer)
1809    self.depthwise_constraint = constraints.get(depthwise_constraint)
1810    self.pointwise_constraint = constraints.get(pointwise_constraint)
1811
1812  def build(self, input_shape):
1813    input_shape = tensor_shape.TensorShape(input_shape)
1814    channel_axis = self._get_channel_axis()
1815    if input_shape.dims[channel_axis].value is None:
1816      raise ValueError('The channel dimension of the inputs '
1817                       'should be defined. Found `None`.')
1818    input_dim = int(input_shape[channel_axis])
1819    self.input_spec = InputSpec(ndim=self.rank + 2,
1820                                axes={channel_axis: input_dim})
1821    depthwise_kernel_shape = self.kernel_size + (input_dim,
1822                                                 self.depth_multiplier)
1823    pointwise_kernel_shape = (
1824        1,) * self.rank + (self.depth_multiplier * input_dim, self.filters)
1825
1826    self.depthwise_kernel = self.add_weight(
1827        name='depthwise_kernel',
1828        shape=depthwise_kernel_shape,
1829        initializer=self.depthwise_initializer,
1830        regularizer=self.depthwise_regularizer,
1831        constraint=self.depthwise_constraint,
1832        trainable=True,
1833        dtype=self.dtype)
1834    self.pointwise_kernel = self.add_weight(
1835        name='pointwise_kernel',
1836        shape=pointwise_kernel_shape,
1837        initializer=self.pointwise_initializer,
1838        regularizer=self.pointwise_regularizer,
1839        constraint=self.pointwise_constraint,
1840        trainable=True,
1841        dtype=self.dtype)
1842    if self.use_bias:
1843      self.bias = self.add_weight(
1844          name='bias',
1845          shape=(self.filters,),
1846          initializer=self.bias_initializer,
1847          regularizer=self.bias_regularizer,
1848          constraint=self.bias_constraint,
1849          trainable=True,
1850          dtype=self.dtype)
1851    else:
1852      self.bias = None
1853    self.built = True
1854
1855  def call(self, inputs):
1856    raise NotImplementedError
1857
1858  def get_config(self):
1859    config = {
1860        'filters':
1861            self.filters,
1862        'kernel_size':
1863            self.kernel_size,
1864        'strides':
1865            self.strides,
1866        'padding':
1867            self.padding,
1868        'data_format':
1869            self.data_format,
1870        'depth_multiplier':
1871            self.depth_multiplier,
1872        'dilation_rate':
1873            self.dilation_rate,
1874        'activation':
1875            activations.serialize(self.activation),
1876        'use_bias':
1877            self.use_bias,
1878        'depthwise_initializer':
1879            initializers.serialize(self.depthwise_initializer),
1880        'pointwise_initializer':
1881            initializers.serialize(self.pointwise_initializer),
1882        'bias_initializer':
1883            initializers.serialize(self.bias_initializer),
1884        'depthwise_regularizer':
1885            regularizers.serialize(self.depthwise_regularizer),
1886        'pointwise_regularizer':
1887            regularizers.serialize(self.pointwise_regularizer),
1888        'bias_regularizer':
1889            regularizers.serialize(self.bias_regularizer),
1890        'activity_regularizer':
1891            regularizers.serialize(self.activity_regularizer),
1892        'depthwise_constraint':
1893            constraints.serialize(self.depthwise_constraint),
1894        'pointwise_constraint':
1895            constraints.serialize(self.pointwise_constraint),
1896        'bias_constraint':
1897            constraints.serialize(self.bias_constraint)
1898    }
1899    base_config = super(SeparableConv, self).get_config()
1900    return dict(list(base_config.items()) + list(config.items()))
1901
1902
1903@keras_export('keras.layers.SeparableConv1D',
1904              'keras.layers.SeparableConvolution1D')
1905class SeparableConv1D(SeparableConv):
1906  """Depthwise separable 1D convolution.
1907
1908  This layer performs a depthwise convolution that acts separately on
1909  channels, followed by a pointwise convolution that mixes channels.
1910  If `use_bias` is True and a bias initializer is provided,
1911  it adds a bias vector to the output.
1912  It then optionally applies an activation function to produce the final output.
1913
1914  Args:
1915    filters: Integer, the dimensionality of the output space (i.e. the number
1916      of filters in the convolution).
1917    kernel_size: A single integer specifying the spatial
1918      dimensions of the filters.
1919    strides: A single integer specifying the strides
1920      of the convolution.
1921      Specifying any `stride` value != 1 is incompatible with specifying
1922      any `dilation_rate` value != 1.
1923    padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive).
1924      `"valid"` means no padding. `"same"` results in padding with zeros evenly
1925      to the left/right or up/down of the input such that output has the same
1926      height/width dimension as the input. `"causal"` results in causal
1927      (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`.
1928    data_format: A string, one of `channels_last` (default) or `channels_first`.
1929      The ordering of the dimensions in the inputs.
1930      `channels_last` corresponds to inputs with shape
1931      `(batch_size, length, channels)` while `channels_first` corresponds to
1932      inputs with shape `(batch_size, channels, length)`.
1933    dilation_rate: A single integer, specifying
1934      the dilation rate to use for dilated convolution.
1935      Currently, specifying any `dilation_rate` value != 1 is
1936      incompatible with specifying any stride value != 1.
1937    depth_multiplier: The number of depthwise convolution output channels for
1938      each input channel. The total number of depthwise convolution output
1939      channels will be equal to `num_filters_in * depth_multiplier`.
1940    activation: Activation function to use.
1941      If you don't specify anything, no activation is applied (
1942      see `keras.activations`).
1943    use_bias: Boolean, whether the layer uses a bias.
1944    depthwise_initializer: An initializer for the depthwise convolution kernel (
1945      see `keras.initializers`). If None, then the default initializer (
1946      'glorot_uniform') will be used.
1947    pointwise_initializer: An initializer for the pointwise convolution kernel (
1948      see `keras.initializers`). If None, then the default initializer
1949      ('glorot_uniform') will be used.
1950    bias_initializer: An initializer for the bias vector. If None, the default
1951      initializer ('zeros') will be used (see `keras.initializers`).
1952    depthwise_regularizer: Optional regularizer for the depthwise
1953      convolution kernel (see `keras.regularizers`).
1954    pointwise_regularizer: Optional regularizer for the pointwise
1955      convolution kernel (see `keras.regularizers`).
1956    bias_regularizer: Optional regularizer for the bias vector (
1957      see `keras.regularizers`).
1958    activity_regularizer: Optional regularizer function for the output (
1959      see `keras.regularizers`).
1960    depthwise_constraint: Optional projection function to be applied to the
1961      depthwise kernel after being updated by an `Optimizer` (e.g. used for
1962      norm constraints or value constraints for layer weights). The function
1963      must take as input the unprojected variable and must return the
1964      projected variable (which must have the same shape). Constraints are
1965      not safe to use when doing asynchronous distributed training (
1966      see `keras.constraints`).
1967    pointwise_constraint: Optional projection function to be applied to the
1968      pointwise kernel after being updated by an `Optimizer` (
1969      see `keras.constraints`).
1970    bias_constraint: Optional projection function to be applied to the
1971      bias after being updated by an `Optimizer` (
1972      see `keras.constraints`).
1973    trainable: Boolean, if `True` the weights of this layer will be marked as
1974      trainable (and listed in `layer.trainable_weights`).
1975
1976  Input shape:
1977    3D tensor with shape:
1978    `(batch_size, channels, steps)` if data_format='channels_first'
1979    or 5D tensor with shape:
1980    `(batch_size, steps, channels)` if data_format='channels_last'.
1981
1982  Output shape:
1983    3D tensor with shape:
1984    `(batch_size, filters, new_steps)` if data_format='channels_first'
1985    or 3D tensor with shape:
1986    `(batch_size,  new_steps, filters)` if data_format='channels_last'.
1987    `new_steps` value might have changed due to padding or strides.
1988
1989  Returns:
1990    A tensor of rank 3 representing
1991    `activation(separableconv1d(inputs, kernel) + bias)`.
1992
1993  Raises:
1994    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
1995  """
1996
1997  def __init__(self,
1998               filters,
1999               kernel_size,
2000               strides=1,
2001               padding='valid',
2002               data_format=None,
2003               dilation_rate=1,
2004               depth_multiplier=1,
2005               activation=None,
2006               use_bias=True,
2007               depthwise_initializer='glorot_uniform',
2008               pointwise_initializer='glorot_uniform',
2009               bias_initializer='zeros',
2010               depthwise_regularizer=None,
2011               pointwise_regularizer=None,
2012               bias_regularizer=None,
2013               activity_regularizer=None,
2014               depthwise_constraint=None,
2015               pointwise_constraint=None,
2016               bias_constraint=None,
2017               **kwargs):
2018    super(SeparableConv1D, self).__init__(
2019        rank=1,
2020        filters=filters,
2021        kernel_size=kernel_size,
2022        strides=strides,
2023        padding=padding,
2024        data_format=data_format,
2025        dilation_rate=dilation_rate,
2026        depth_multiplier=depth_multiplier,
2027        activation=activations.get(activation),
2028        use_bias=use_bias,
2029        depthwise_initializer=initializers.get(depthwise_initializer),
2030        pointwise_initializer=initializers.get(pointwise_initializer),
2031        bias_initializer=initializers.get(bias_initializer),
2032        depthwise_regularizer=regularizers.get(depthwise_regularizer),
2033        pointwise_regularizer=regularizers.get(pointwise_regularizer),
2034        bias_regularizer=regularizers.get(bias_regularizer),
2035        activity_regularizer=regularizers.get(activity_regularizer),
2036        depthwise_constraint=constraints.get(depthwise_constraint),
2037        pointwise_constraint=constraints.get(pointwise_constraint),
2038        bias_constraint=constraints.get(bias_constraint),
2039        **kwargs)
2040
2041  def call(self, inputs):
2042    if self.padding == 'causal':
2043      inputs = array_ops.pad(inputs, self._compute_causal_padding(inputs))
2044    if self.data_format == 'channels_last':
2045      strides = (1,) + self.strides * 2 + (1,)
2046      spatial_start_dim = 1
2047    else:
2048      strides = (1, 1) + self.strides * 2
2049      spatial_start_dim = 2
2050
2051    # Explicitly broadcast inputs and kernels to 4D.
2052    # TODO(fchollet): refactor when a native separable_conv1d op is available.
2053    inputs = array_ops.expand_dims(inputs, spatial_start_dim)
2054    depthwise_kernel = array_ops.expand_dims(self.depthwise_kernel, 0)
2055    pointwise_kernel = array_ops.expand_dims(self.pointwise_kernel, 0)
2056    dilation_rate = (1,) + self.dilation_rate
2057
2058    if self.padding == 'causal':
2059      op_padding = 'valid'
2060    else:
2061      op_padding = self.padding
2062    outputs = nn.separable_conv2d(
2063        inputs,
2064        depthwise_kernel,
2065        pointwise_kernel,
2066        strides=strides,
2067        padding=op_padding.upper(),
2068        rate=dilation_rate,
2069        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
2070
2071    if self.use_bias:
2072      outputs = nn.bias_add(
2073          outputs,
2074          self.bias,
2075          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
2076
2077    outputs = array_ops.squeeze(outputs, [spatial_start_dim])
2078
2079    if self.activation is not None:
2080      return self.activation(outputs)
2081    return outputs
2082
2083
2084@keras_export('keras.layers.SeparableConv2D',
2085              'keras.layers.SeparableConvolution2D')
2086class SeparableConv2D(SeparableConv):
2087  """Depthwise separable 2D convolution.
2088
2089  Separable convolutions consist of first performing
2090  a depthwise spatial convolution
2091  (which acts on each input channel separately)
2092  followed by a pointwise convolution which mixes the resulting
2093  output channels. The `depth_multiplier` argument controls how many
2094  output channels are generated per input channel in the depthwise step.
2095
2096  Intuitively, separable convolutions can be understood as
2097  a way to factorize a convolution kernel into two smaller kernels,
2098  or as an extreme version of an Inception block.
2099
2100  Args:
2101    filters: Integer, the dimensionality of the output space
2102      (i.e. the number of output filters in the convolution).
2103    kernel_size: An integer or tuple/list of 2 integers, specifying the
2104      height and width of the 2D convolution window.
2105      Can be a single integer to specify the same value for
2106      all spatial dimensions.
2107    strides: An integer or tuple/list of 2 integers,
2108      specifying the strides of the convolution along the height and width.
2109      Can be a single integer to specify the same value for
2110      all spatial dimensions.
2111      Specifying any stride value != 1 is incompatible with specifying
2112      any `dilation_rate` value != 1.
2113    padding: one of `"valid"` or `"same"` (case-insensitive).
2114      `"valid"` means no padding. `"same"` results in padding with zeros evenly
2115      to the left/right or up/down of the input such that output has the same
2116      height/width dimension as the input.
2117    data_format: A string,
2118      one of `channels_last` (default) or `channels_first`.
2119      The ordering of the dimensions in the inputs.
2120      `channels_last` corresponds to inputs with shape
2121      `(batch_size, height, width, channels)` while `channels_first`
2122      corresponds to inputs with shape
2123      `(batch_size, channels, height, width)`.
2124      It defaults to the `image_data_format` value found in your
2125      Keras config file at `~/.keras/keras.json`.
2126      If you never set it, then it will be "channels_last".
2127    dilation_rate: An integer or tuple/list of 2 integers, specifying
2128      the dilation rate to use for dilated convolution.
2129      Currently, specifying any `dilation_rate` value != 1 is
2130      incompatible with specifying any `strides` value != 1.
2131    depth_multiplier: The number of depthwise convolution output channels
2132      for each input channel.
2133      The total number of depthwise convolution output
2134      channels will be equal to `filters_in * depth_multiplier`.
2135    activation: Activation function to use.
2136      If you don't specify anything, no activation is applied (
2137      see `keras.activations`).
2138    use_bias: Boolean, whether the layer uses a bias vector.
2139    depthwise_initializer: An initializer for the depthwise convolution kernel (
2140      see `keras.initializers`). If None, then the default initializer (
2141      'glorot_uniform') will be used.
2142    pointwise_initializer: An initializer for the pointwise convolution kernel (
2143      see `keras.initializers`). If None, then the default initializer
2144      ('glorot_uniform') will be used.
2145    bias_initializer: An initializer for the bias vector. If None, the default
2146      initializer ('zeros') will be used (see `keras.initializers`).
2147    depthwise_regularizer: Regularizer function applied to
2148      the depthwise kernel matrix (see `keras.regularizers`).
2149    pointwise_regularizer: Regularizer function applied to
2150      the pointwise kernel matrix (see `keras.regularizers`).
2151    bias_regularizer: Regularizer function applied to the bias vector (
2152      see `keras.regularizers`).
2153    activity_regularizer: Regularizer function applied to
2154      the output of the layer (its "activation") (
2155      see `keras.regularizers`).
2156    depthwise_constraint: Constraint function applied to
2157      the depthwise kernel matrix (
2158      see `keras.constraints`).
2159    pointwise_constraint: Constraint function applied to
2160      the pointwise kernel matrix (
2161      see `keras.constraints`).
2162    bias_constraint: Constraint function applied to the bias vector (
2163      see `keras.constraints`).
2164
2165  Input shape:
2166    4D tensor with shape:
2167    `(batch_size, channels, rows, cols)` if data_format='channels_first'
2168    or 4D tensor with shape:
2169    `(batch_size, rows, cols, channels)` if data_format='channels_last'.
2170
2171  Output shape:
2172    4D tensor with shape:
2173    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
2174    or 4D tensor with shape:
2175    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
2176    `rows` and `cols` values might have changed due to padding.
2177
2178  Returns:
2179    A tensor of rank 4 representing
2180    `activation(separableconv2d(inputs, kernel) + bias)`.
2181
2182  Raises:
2183    ValueError: if `padding` is "causal".
2184    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
2185  """
2186
2187  def __init__(self,
2188               filters,
2189               kernel_size,
2190               strides=(1, 1),
2191               padding='valid',
2192               data_format=None,
2193               dilation_rate=(1, 1),
2194               depth_multiplier=1,
2195               activation=None,
2196               use_bias=True,
2197               depthwise_initializer='glorot_uniform',
2198               pointwise_initializer='glorot_uniform',
2199               bias_initializer='zeros',
2200               depthwise_regularizer=None,
2201               pointwise_regularizer=None,
2202               bias_regularizer=None,
2203               activity_regularizer=None,
2204               depthwise_constraint=None,
2205               pointwise_constraint=None,
2206               bias_constraint=None,
2207               **kwargs):
2208    super(SeparableConv2D, self).__init__(
2209        rank=2,
2210        filters=filters,
2211        kernel_size=kernel_size,
2212        strides=strides,
2213        padding=padding,
2214        data_format=data_format,
2215        dilation_rate=dilation_rate,
2216        depth_multiplier=depth_multiplier,
2217        activation=activations.get(activation),
2218        use_bias=use_bias,
2219        depthwise_initializer=initializers.get(depthwise_initializer),
2220        pointwise_initializer=initializers.get(pointwise_initializer),
2221        bias_initializer=initializers.get(bias_initializer),
2222        depthwise_regularizer=regularizers.get(depthwise_regularizer),
2223        pointwise_regularizer=regularizers.get(pointwise_regularizer),
2224        bias_regularizer=regularizers.get(bias_regularizer),
2225        activity_regularizer=regularizers.get(activity_regularizer),
2226        depthwise_constraint=constraints.get(depthwise_constraint),
2227        pointwise_constraint=constraints.get(pointwise_constraint),
2228        bias_constraint=constraints.get(bias_constraint),
2229        **kwargs)
2230
2231  def call(self, inputs):
2232    # Apply the actual ops.
2233    if self.data_format == 'channels_last':
2234      strides = (1,) + self.strides + (1,)
2235    else:
2236      strides = (1, 1) + self.strides
2237    outputs = nn.separable_conv2d(
2238        inputs,
2239        self.depthwise_kernel,
2240        self.pointwise_kernel,
2241        strides=strides,
2242        padding=self.padding.upper(),
2243        rate=self.dilation_rate,
2244        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
2245
2246    if self.use_bias:
2247      outputs = nn.bias_add(
2248          outputs,
2249          self.bias,
2250          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
2251
2252    if self.activation is not None:
2253      return self.activation(outputs)
2254    return outputs
2255
2256
2257@keras_export('keras.layers.DepthwiseConv2D')
2258class DepthwiseConv2D(Conv2D):
2259  """Depthwise separable 2D convolution.
2260
2261  Depthwise Separable convolutions consist of performing
2262  just the first step in a depthwise spatial convolution
2263  (which acts on each input channel separately).
2264  The `depth_multiplier` argument controls how many
2265  output channels are generated per input channel in the depthwise step.
2266
2267  Args:
2268    kernel_size: An integer or tuple/list of 2 integers, specifying the
2269      height and width of the 2D convolution window.
2270      Can be a single integer to specify the same value for
2271      all spatial dimensions.
2272    strides: An integer or tuple/list of 2 integers,
2273      specifying the strides of the convolution along the height and width.
2274      Can be a single integer to specify the same value for
2275      all spatial dimensions.
2276      Specifying any stride value != 1 is incompatible with specifying
2277      any `dilation_rate` value != 1.
2278    padding: one of `'valid'` or `'same'` (case-insensitive).
2279      `"valid"` means no padding. `"same"` results in padding with zeros evenly
2280      to the left/right or up/down of the input such that output has the same
2281      height/width dimension as the input.
2282    depth_multiplier: The number of depthwise convolution output channels
2283      for each input channel.
2284      The total number of depthwise convolution output
2285      channels will be equal to `filters_in * depth_multiplier`.
2286    data_format: A string,
2287      one of `channels_last` (default) or `channels_first`.
2288      The ordering of the dimensions in the inputs.
2289      `channels_last` corresponds to inputs with shape
2290      `(batch_size, height, width, channels)` while `channels_first`
2291      corresponds to inputs with shape
2292      `(batch_size, channels, height, width)`.
2293      It defaults to the `image_data_format` value found in your
2294      Keras config file at `~/.keras/keras.json`.
2295      If you never set it, then it will be 'channels_last'.
2296    dilation_rate: An integer or tuple/list of 2 integers, specifying
2297      the dilation rate to use for dilated convolution.
2298      Currently, specifying any `dilation_rate` value != 1 is
2299      incompatible with specifying any `strides` value != 1.
2300    activation: Activation function to use.
2301      If you don't specify anything, no activation is applied (
2302      see `keras.activations`).
2303    use_bias: Boolean, whether the layer uses a bias vector.
2304    depthwise_initializer: Initializer for the depthwise kernel matrix (
2305      see `keras.initializers`). If None, the default initializer (
2306      'glorot_uniform') will be used.
2307    bias_initializer: Initializer for the bias vector (
2308      see `keras.initializers`). If None, the default initializer (
2309      'zeros') will bs used.
2310    depthwise_regularizer: Regularizer function applied to
2311      the depthwise kernel matrix (see `keras.regularizers`).
2312    bias_regularizer: Regularizer function applied to the bias vector (
2313      see `keras.regularizers`).
2314    activity_regularizer: Regularizer function applied to
2315      the output of the layer (its 'activation') (
2316      see `keras.regularizers`).
2317    depthwise_constraint: Constraint function applied to
2318      the depthwise kernel matrix (
2319      see `keras.constraints`).
2320    bias_constraint: Constraint function applied to the bias vector (
2321      see `keras.constraints`).
2322
2323  Input shape:
2324    4D tensor with shape:
2325    `[batch_size, channels, rows, cols]` if data_format='channels_first'
2326    or 4D tensor with shape:
2327    `[batch_size, rows, cols, channels]` if data_format='channels_last'.
2328
2329  Output shape:
2330    4D tensor with shape:
2331    `[batch_size, filters, new_rows, new_cols]` if data_format='channels_first'
2332    or 4D tensor with shape:
2333    `[batch_size, new_rows, new_cols, filters]` if data_format='channels_last'.
2334    `rows` and `cols` values might have changed due to padding.
2335
2336  Returns:
2337    A tensor of rank 4 representing
2338    `activation(depthwiseconv2d(inputs, kernel) + bias)`.
2339
2340  Raises:
2341    ValueError: if `padding` is "causal".
2342    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
2343  """
2344
2345  def __init__(self,
2346               kernel_size,
2347               strides=(1, 1),
2348               padding='valid',
2349               depth_multiplier=1,
2350               data_format=None,
2351               dilation_rate=(1, 1),
2352               activation=None,
2353               use_bias=True,
2354               depthwise_initializer='glorot_uniform',
2355               bias_initializer='zeros',
2356               depthwise_regularizer=None,
2357               bias_regularizer=None,
2358               activity_regularizer=None,
2359               depthwise_constraint=None,
2360               bias_constraint=None,
2361               **kwargs):
2362    super(DepthwiseConv2D, self).__init__(
2363        filters=None,
2364        kernel_size=kernel_size,
2365        strides=strides,
2366        padding=padding,
2367        data_format=data_format,
2368        dilation_rate=dilation_rate,
2369        activation=activation,
2370        use_bias=use_bias,
2371        bias_regularizer=bias_regularizer,
2372        activity_regularizer=activity_regularizer,
2373        bias_constraint=bias_constraint,
2374        **kwargs)
2375    self.depth_multiplier = depth_multiplier
2376    self.depthwise_initializer = initializers.get(depthwise_initializer)
2377    self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
2378    self.depthwise_constraint = constraints.get(depthwise_constraint)
2379    self.bias_initializer = initializers.get(bias_initializer)
2380
2381  def build(self, input_shape):
2382    if len(input_shape) < 4:
2383      raise ValueError('Inputs to `DepthwiseConv2D` should have rank 4. '
2384                       'Received input shape:', str(input_shape))
2385    input_shape = tensor_shape.TensorShape(input_shape)
2386    channel_axis = self._get_channel_axis()
2387    if input_shape.dims[channel_axis].value is None:
2388      raise ValueError('The channel dimension of the inputs to '
2389                       '`DepthwiseConv2D` '
2390                       'should be defined. Found `None`.')
2391    input_dim = int(input_shape[channel_axis])
2392    depthwise_kernel_shape = (self.kernel_size[0],
2393                              self.kernel_size[1],
2394                              input_dim,
2395                              self.depth_multiplier)
2396
2397    self.depthwise_kernel = self.add_weight(
2398        shape=depthwise_kernel_shape,
2399        initializer=self.depthwise_initializer,
2400        name='depthwise_kernel',
2401        regularizer=self.depthwise_regularizer,
2402        constraint=self.depthwise_constraint)
2403
2404    if self.use_bias:
2405      self.bias = self.add_weight(shape=(input_dim * self.depth_multiplier,),
2406                                  initializer=self.bias_initializer,
2407                                  name='bias',
2408                                  regularizer=self.bias_regularizer,
2409                                  constraint=self.bias_constraint)
2410    else:
2411      self.bias = None
2412    # Set input spec.
2413    self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
2414    self.built = True
2415
2416  def call(self, inputs):
2417    outputs = backend.depthwise_conv2d(
2418        inputs,
2419        self.depthwise_kernel,
2420        strides=self.strides,
2421        padding=self.padding,
2422        dilation_rate=self.dilation_rate,
2423        data_format=self.data_format)
2424
2425    if self.use_bias:
2426      outputs = backend.bias_add(
2427          outputs,
2428          self.bias,
2429          data_format=self.data_format)
2430
2431    if self.activation is not None:
2432      return self.activation(outputs)
2433
2434    return outputs
2435
2436  @tf_utils.shape_type_conversion
2437  def compute_output_shape(self, input_shape):
2438    if self.data_format == 'channels_first':
2439      rows = input_shape[2]
2440      cols = input_shape[3]
2441      out_filters = input_shape[1] * self.depth_multiplier
2442    elif self.data_format == 'channels_last':
2443      rows = input_shape[1]
2444      cols = input_shape[2]
2445      out_filters = input_shape[3] * self.depth_multiplier
2446
2447    rows = conv_utils.conv_output_length(rows, self.kernel_size[0],
2448                                         self.padding,
2449                                         self.strides[0],
2450                                         self.dilation_rate[0])
2451    cols = conv_utils.conv_output_length(cols, self.kernel_size[1],
2452                                         self.padding,
2453                                         self.strides[1],
2454                                         self.dilation_rate[1])
2455    if self.data_format == 'channels_first':
2456      return (input_shape[0], out_filters, rows, cols)
2457    elif self.data_format == 'channels_last':
2458      return (input_shape[0], rows, cols, out_filters)
2459
2460  def get_config(self):
2461    config = super(DepthwiseConv2D, self).get_config()
2462    config.pop('filters')
2463    config.pop('kernel_initializer')
2464    config.pop('kernel_regularizer')
2465    config.pop('kernel_constraint')
2466    config['depth_multiplier'] = self.depth_multiplier
2467    config['depthwise_initializer'] = initializers.serialize(
2468        self.depthwise_initializer)
2469    config['depthwise_regularizer'] = regularizers.serialize(
2470        self.depthwise_regularizer)
2471    config['depthwise_constraint'] = constraints.serialize(
2472        self.depthwise_constraint)
2473    return config
2474
2475
2476@keras_export('keras.layers.UpSampling1D')
2477class UpSampling1D(Layer):
2478  """Upsampling layer for 1D inputs.
2479
2480  Repeats each temporal step `size` times along the time axis.
2481
2482  Examples:
2483
2484  >>> input_shape = (2, 2, 3)
2485  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
2486  >>> print(x)
2487  [[[ 0  1  2]
2488    [ 3  4  5]]
2489   [[ 6  7  8]
2490    [ 9 10 11]]]
2491  >>> y = tf.keras.layers.UpSampling1D(size=2)(x)
2492  >>> print(y)
2493  tf.Tensor(
2494    [[[ 0  1  2]
2495      [ 0  1  2]
2496      [ 3  4  5]
2497      [ 3  4  5]]
2498     [[ 6  7  8]
2499      [ 6  7  8]
2500      [ 9 10 11]
2501      [ 9 10 11]]], shape=(2, 4, 3), dtype=int64)
2502
2503  Args:
2504    size: Integer. Upsampling factor.
2505
2506  Input shape:
2507    3D tensor with shape: `(batch_size, steps, features)`.
2508
2509  Output shape:
2510    3D tensor with shape: `(batch_size, upsampled_steps, features)`.
2511  """
2512
2513  def __init__(self, size=2, **kwargs):
2514    super(UpSampling1D, self).__init__(**kwargs)
2515    self.size = int(size)
2516    self.input_spec = InputSpec(ndim=3)
2517
2518  def compute_output_shape(self, input_shape):
2519    input_shape = tensor_shape.TensorShape(input_shape).as_list()
2520    size = self.size * input_shape[1] if input_shape[1] is not None else None
2521    return tensor_shape.TensorShape([input_shape[0], size, input_shape[2]])
2522
2523  def call(self, inputs):
2524    output = backend.repeat_elements(inputs, self.size, axis=1)
2525    return output
2526
2527  def get_config(self):
2528    config = {'size': self.size}
2529    base_config = super(UpSampling1D, self).get_config()
2530    return dict(list(base_config.items()) + list(config.items()))
2531
2532
2533@keras_export('keras.layers.UpSampling2D')
2534class UpSampling2D(Layer):
2535  """Upsampling layer for 2D inputs.
2536
2537  Repeats the rows and columns of the data
2538  by `size[0]` and `size[1]` respectively.
2539
2540  Examples:
2541
2542  >>> input_shape = (2, 2, 1, 3)
2543  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
2544  >>> print(x)
2545  [[[[ 0  1  2]]
2546    [[ 3  4  5]]]
2547   [[[ 6  7  8]]
2548    [[ 9 10 11]]]]
2549  >>> y = tf.keras.layers.UpSampling2D(size=(1, 2))(x)
2550  >>> print(y)
2551  tf.Tensor(
2552    [[[[ 0  1  2]
2553       [ 0  1  2]]
2554      [[ 3  4  5]
2555       [ 3  4  5]]]
2556     [[[ 6  7  8]
2557       [ 6  7  8]]
2558      [[ 9 10 11]
2559       [ 9 10 11]]]], shape=(2, 2, 2, 3), dtype=int64)
2560
2561  Args:
2562    size: Int, or tuple of 2 integers.
2563      The upsampling factors for rows and columns.
2564    data_format: A string,
2565      one of `channels_last` (default) or `channels_first`.
2566      The ordering of the dimensions in the inputs.
2567      `channels_last` corresponds to inputs with shape
2568      `(batch_size, height, width, channels)` while `channels_first`
2569      corresponds to inputs with shape
2570      `(batch_size, channels, height, width)`.
2571      It defaults to the `image_data_format` value found in your
2572      Keras config file at `~/.keras/keras.json`.
2573      If you never set it, then it will be "channels_last".
2574    interpolation: A string, one of `nearest` or `bilinear`.
2575
2576  Input shape:
2577    4D tensor with shape:
2578    - If `data_format` is `"channels_last"`:
2579        `(batch_size, rows, cols, channels)`
2580    - If `data_format` is `"channels_first"`:
2581        `(batch_size, channels, rows, cols)`
2582
2583  Output shape:
2584    4D tensor with shape:
2585    - If `data_format` is `"channels_last"`:
2586        `(batch_size, upsampled_rows, upsampled_cols, channels)`
2587    - If `data_format` is `"channels_first"`:
2588        `(batch_size, channels, upsampled_rows, upsampled_cols)`
2589  """
2590
2591  def __init__(self,
2592               size=(2, 2),
2593               data_format=None,
2594               interpolation='nearest',
2595               **kwargs):
2596    super(UpSampling2D, self).__init__(**kwargs)
2597    self.data_format = conv_utils.normalize_data_format(data_format)
2598    self.size = conv_utils.normalize_tuple(size, 2, 'size')
2599    if interpolation not in {'nearest', 'bilinear'}:
2600      raise ValueError('`interpolation` argument should be one of `"nearest"` '
2601                       'or `"bilinear"`.')
2602    self.interpolation = interpolation
2603    self.input_spec = InputSpec(ndim=4)
2604
2605  def compute_output_shape(self, input_shape):
2606    input_shape = tensor_shape.TensorShape(input_shape).as_list()
2607    if self.data_format == 'channels_first':
2608      height = self.size[0] * input_shape[
2609          2] if input_shape[2] is not None else None
2610      width = self.size[1] * input_shape[
2611          3] if input_shape[3] is not None else None
2612      return tensor_shape.TensorShape(
2613          [input_shape[0], input_shape[1], height, width])
2614    else:
2615      height = self.size[0] * input_shape[
2616          1] if input_shape[1] is not None else None
2617      width = self.size[1] * input_shape[
2618          2] if input_shape[2] is not None else None
2619      return tensor_shape.TensorShape(
2620          [input_shape[0], height, width, input_shape[3]])
2621
2622  def call(self, inputs):
2623    return backend.resize_images(
2624        inputs, self.size[0], self.size[1], self.data_format,
2625        interpolation=self.interpolation)
2626
2627  def get_config(self):
2628    config = {
2629        'size': self.size,
2630        'data_format': self.data_format,
2631        'interpolation': self.interpolation
2632    }
2633    base_config = super(UpSampling2D, self).get_config()
2634    return dict(list(base_config.items()) + list(config.items()))
2635
2636
2637@keras_export('keras.layers.UpSampling3D')
2638class UpSampling3D(Layer):
2639  """Upsampling layer for 3D inputs.
2640
2641  Repeats the 1st, 2nd and 3rd dimensions
2642  of the data by `size[0]`, `size[1]` and `size[2]` respectively.
2643
2644  Examples:
2645
2646  >>> input_shape = (2, 1, 2, 1, 3)
2647  >>> x = tf.constant(1, shape=input_shape)
2648  >>> y = tf.keras.layers.UpSampling3D(size=2)(x)
2649  >>> print(y.shape)
2650  (2, 2, 4, 2, 3)
2651
2652  Args:
2653    size: Int, or tuple of 3 integers.
2654      The upsampling factors for dim1, dim2 and dim3.
2655    data_format: A string,
2656      one of `channels_last` (default) or `channels_first`.
2657      The ordering of the dimensions in the inputs.
2658      `channels_last` corresponds to inputs with shape
2659      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
2660      while `channels_first` corresponds to inputs with shape
2661      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
2662      It defaults to the `image_data_format` value found in your
2663      Keras config file at `~/.keras/keras.json`.
2664      If you never set it, then it will be "channels_last".
2665
2666  Input shape:
2667    5D tensor with shape:
2668    - If `data_format` is `"channels_last"`:
2669        `(batch_size, dim1, dim2, dim3, channels)`
2670    - If `data_format` is `"channels_first"`:
2671        `(batch_size, channels, dim1, dim2, dim3)`
2672
2673  Output shape:
2674    5D tensor with shape:
2675    - If `data_format` is `"channels_last"`:
2676        `(batch_size, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)`
2677    - If `data_format` is `"channels_first"`:
2678        `(batch_size, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)`
2679  """
2680
2681  def __init__(self, size=(2, 2, 2), data_format=None, **kwargs):
2682    self.data_format = conv_utils.normalize_data_format(data_format)
2683    self.size = conv_utils.normalize_tuple(size, 3, 'size')
2684    self.input_spec = InputSpec(ndim=5)
2685    super(UpSampling3D, self).__init__(**kwargs)
2686
2687  def compute_output_shape(self, input_shape):
2688    input_shape = tensor_shape.TensorShape(input_shape).as_list()
2689    if self.data_format == 'channels_first':
2690      dim1 = self.size[0] * input_shape[
2691          2] if input_shape[2] is not None else None
2692      dim2 = self.size[1] * input_shape[
2693          3] if input_shape[3] is not None else None
2694      dim3 = self.size[2] * input_shape[
2695          4] if input_shape[4] is not None else None
2696      return tensor_shape.TensorShape(
2697          [input_shape[0], input_shape[1], dim1, dim2, dim3])
2698    else:
2699      dim1 = self.size[0] * input_shape[
2700          1] if input_shape[1] is not None else None
2701      dim2 = self.size[1] * input_shape[
2702          2] if input_shape[2] is not None else None
2703      dim3 = self.size[2] * input_shape[
2704          3] if input_shape[3] is not None else None
2705      return tensor_shape.TensorShape(
2706          [input_shape[0], dim1, dim2, dim3, input_shape[4]])
2707
2708  def call(self, inputs):
2709    return backend.resize_volumes(
2710        inputs, self.size[0], self.size[1], self.size[2], self.data_format)
2711
2712  def get_config(self):
2713    config = {'size': self.size, 'data_format': self.data_format}
2714    base_config = super(UpSampling3D, self).get_config()
2715    return dict(list(base_config.items()) + list(config.items()))
2716
2717
2718@keras_export('keras.layers.ZeroPadding1D')
2719class ZeroPadding1D(Layer):
2720  """Zero-padding layer for 1D input (e.g. temporal sequence).
2721
2722  Examples:
2723
2724  >>> input_shape = (2, 2, 3)
2725  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
2726  >>> print(x)
2727  [[[ 0  1  2]
2728    [ 3  4  5]]
2729   [[ 6  7  8]
2730    [ 9 10 11]]]
2731  >>> y = tf.keras.layers.ZeroPadding1D(padding=2)(x)
2732  >>> print(y)
2733  tf.Tensor(
2734    [[[ 0  0  0]
2735      [ 0  0  0]
2736      [ 0  1  2]
2737      [ 3  4  5]
2738      [ 0  0  0]
2739      [ 0  0  0]]
2740     [[ 0  0  0]
2741      [ 0  0  0]
2742      [ 6  7  8]
2743      [ 9 10 11]
2744      [ 0  0  0]
2745      [ 0  0  0]]], shape=(2, 6, 3), dtype=int64)
2746
2747  Args:
2748      padding: Int, or tuple of int (length 2), or dictionary.
2749          - If int:
2750          How many zeros to add at the beginning and end of
2751          the padding dimension (axis 1).
2752          - If tuple of int (length 2):
2753          How many zeros to add at the beginning and the end of
2754          the padding dimension (`(left_pad, right_pad)`).
2755
2756  Input shape:
2757      3D tensor with shape `(batch_size, axis_to_pad, features)`
2758
2759  Output shape:
2760      3D tensor with shape `(batch_size, padded_axis, features)`
2761  """
2762
2763  def __init__(self, padding=1, **kwargs):
2764    super(ZeroPadding1D, self).__init__(**kwargs)
2765    self.padding = conv_utils.normalize_tuple(padding, 2, 'padding')
2766    self.input_spec = InputSpec(ndim=3)
2767
2768  def compute_output_shape(self, input_shape):
2769    if input_shape[1] is not None:
2770      length = input_shape[1] + self.padding[0] + self.padding[1]
2771    else:
2772      length = None
2773    return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]])
2774
2775  def call(self, inputs):
2776    return backend.temporal_padding(inputs, padding=self.padding)
2777
2778  def get_config(self):
2779    config = {'padding': self.padding}
2780    base_config = super(ZeroPadding1D, self).get_config()
2781    return dict(list(base_config.items()) + list(config.items()))
2782
2783
2784@keras_export('keras.layers.ZeroPadding2D')
2785class ZeroPadding2D(Layer):
2786  """Zero-padding layer for 2D input (e.g. picture).
2787
2788  This layer can add rows and columns of zeros
2789  at the top, bottom, left and right side of an image tensor.
2790
2791  Examples:
2792
2793  >>> input_shape = (1, 1, 2, 2)
2794  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
2795  >>> print(x)
2796  [[[[0 1]
2797     [2 3]]]]
2798  >>> y = tf.keras.layers.ZeroPadding2D(padding=1)(x)
2799  >>> print(y)
2800  tf.Tensor(
2801    [[[[0 0]
2802       [0 0]
2803       [0 0]
2804       [0 0]]
2805      [[0 0]
2806       [0 1]
2807       [2 3]
2808       [0 0]]
2809      [[0 0]
2810       [0 0]
2811       [0 0]
2812       [0 0]]]], shape=(1, 3, 4, 2), dtype=int64)
2813
2814  Args:
2815    padding: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
2816      - If int: the same symmetric padding
2817        is applied to height and width.
2818      - If tuple of 2 ints:
2819        interpreted as two different
2820        symmetric padding values for height and width:
2821        `(symmetric_height_pad, symmetric_width_pad)`.
2822      - If tuple of 2 tuples of 2 ints:
2823        interpreted as
2824        `((top_pad, bottom_pad), (left_pad, right_pad))`
2825    data_format: A string,
2826      one of `channels_last` (default) or `channels_first`.
2827      The ordering of the dimensions in the inputs.
2828      `channels_last` corresponds to inputs with shape
2829      `(batch_size, height, width, channels)` while `channels_first`
2830      corresponds to inputs with shape
2831      `(batch_size, channels, height, width)`.
2832      It defaults to the `image_data_format` value found in your
2833      Keras config file at `~/.keras/keras.json`.
2834      If you never set it, then it will be "channels_last".
2835
2836  Input shape:
2837    4D tensor with shape:
2838    - If `data_format` is `"channels_last"`:
2839        `(batch_size, rows, cols, channels)`
2840    - If `data_format` is `"channels_first"`:
2841        `(batch_size, channels, rows, cols)`
2842
2843  Output shape:
2844    4D tensor with shape:
2845    - If `data_format` is `"channels_last"`:
2846        `(batch_size, padded_rows, padded_cols, channels)`
2847    - If `data_format` is `"channels_first"`:
2848        `(batch_size, channels, padded_rows, padded_cols)`
2849  """
2850
2851  def __init__(self, padding=(1, 1), data_format=None, **kwargs):
2852    super(ZeroPadding2D, self).__init__(**kwargs)
2853    self.data_format = conv_utils.normalize_data_format(data_format)
2854    if isinstance(padding, int):
2855      self.padding = ((padding, padding), (padding, padding))
2856    elif hasattr(padding, '__len__'):
2857      if len(padding) != 2:
2858        raise ValueError('`padding` should have two elements. '
2859                         'Found: ' + str(padding))
2860      height_padding = conv_utils.normalize_tuple(padding[0], 2,
2861                                                  '1st entry of padding')
2862      width_padding = conv_utils.normalize_tuple(padding[1], 2,
2863                                                 '2nd entry of padding')
2864      self.padding = (height_padding, width_padding)
2865    else:
2866      raise ValueError('`padding` should be either an int, '
2867                       'a tuple of 2 ints '
2868                       '(symmetric_height_pad, symmetric_width_pad), '
2869                       'or a tuple of 2 tuples of 2 ints '
2870                       '((top_pad, bottom_pad), (left_pad, right_pad)). '
2871                       'Found: ' + str(padding))
2872    self.input_spec = InputSpec(ndim=4)
2873
2874  def compute_output_shape(self, input_shape):
2875    input_shape = tensor_shape.TensorShape(input_shape).as_list()
2876    if self.data_format == 'channels_first':
2877      if input_shape[2] is not None:
2878        rows = input_shape[2] + self.padding[0][0] + self.padding[0][1]
2879      else:
2880        rows = None
2881      if input_shape[3] is not None:
2882        cols = input_shape[3] + self.padding[1][0] + self.padding[1][1]
2883      else:
2884        cols = None
2885      return tensor_shape.TensorShape(
2886          [input_shape[0], input_shape[1], rows, cols])
2887    elif self.data_format == 'channels_last':
2888      if input_shape[1] is not None:
2889        rows = input_shape[1] + self.padding[0][0] + self.padding[0][1]
2890      else:
2891        rows = None
2892      if input_shape[2] is not None:
2893        cols = input_shape[2] + self.padding[1][0] + self.padding[1][1]
2894      else:
2895        cols = None
2896      return tensor_shape.TensorShape(
2897          [input_shape[0], rows, cols, input_shape[3]])
2898
2899  def call(self, inputs):
2900    return backend.spatial_2d_padding(
2901        inputs, padding=self.padding, data_format=self.data_format)
2902
2903  def get_config(self):
2904    config = {'padding': self.padding, 'data_format': self.data_format}
2905    base_config = super(ZeroPadding2D, self).get_config()
2906    return dict(list(base_config.items()) + list(config.items()))
2907
2908
2909@keras_export('keras.layers.ZeroPadding3D')
2910class ZeroPadding3D(Layer):
2911  """Zero-padding layer for 3D data (spatial or spatio-temporal).
2912
2913  Examples:
2914
2915  >>> input_shape = (1, 1, 2, 2, 3)
2916  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
2917  >>> y = tf.keras.layers.ZeroPadding3D(padding=2)(x)
2918  >>> print(y.shape)
2919  (1, 5, 6, 6, 3)
2920
2921  Args:
2922    padding: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints.
2923      - If int: the same symmetric padding
2924        is applied to height and width.
2925      - If tuple of 3 ints:
2926        interpreted as two different
2927        symmetric padding values for height and width:
2928        `(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad)`.
2929      - If tuple of 3 tuples of 2 ints:
2930        interpreted as
2931        `((left_dim1_pad, right_dim1_pad), (left_dim2_pad,
2932          right_dim2_pad), (left_dim3_pad, right_dim3_pad))`
2933    data_format: A string,
2934      one of `channels_last` (default) or `channels_first`.
2935      The ordering of the dimensions in the inputs.
2936      `channels_last` corresponds to inputs with shape
2937      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
2938      while `channels_first` corresponds to inputs with shape
2939      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
2940      It defaults to the `image_data_format` value found in your
2941      Keras config file at `~/.keras/keras.json`.
2942      If you never set it, then it will be "channels_last".
2943
2944  Input shape:
2945    5D tensor with shape:
2946    - If `data_format` is `"channels_last"`:
2947        `(batch_size, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad,
2948          depth)`
2949    - If `data_format` is `"channels_first"`:
2950        `(batch_size, depth, first_axis_to_pad, second_axis_to_pad,
2951          third_axis_to_pad)`
2952
2953  Output shape:
2954    5D tensor with shape:
2955    - If `data_format` is `"channels_last"`:
2956        `(batch_size, first_padded_axis, second_padded_axis, third_axis_to_pad,
2957          depth)`
2958    - If `data_format` is `"channels_first"`:
2959        `(batch_size, depth, first_padded_axis, second_padded_axis,
2960          third_axis_to_pad)`
2961  """
2962
2963  def __init__(self, padding=(1, 1, 1), data_format=None, **kwargs):
2964    super(ZeroPadding3D, self).__init__(**kwargs)
2965    self.data_format = conv_utils.normalize_data_format(data_format)
2966    if isinstance(padding, int):
2967      self.padding = ((padding, padding), (padding, padding), (padding,
2968                                                               padding))
2969    elif hasattr(padding, '__len__'):
2970      if len(padding) != 3:
2971        raise ValueError('`padding` should have 3 elements. '
2972                         'Found: ' + str(padding))
2973      dim1_padding = conv_utils.normalize_tuple(padding[0], 2,
2974                                                '1st entry of padding')
2975      dim2_padding = conv_utils.normalize_tuple(padding[1], 2,
2976                                                '2nd entry of padding')
2977      dim3_padding = conv_utils.normalize_tuple(padding[2], 2,
2978                                                '3rd entry of padding')
2979      self.padding = (dim1_padding, dim2_padding, dim3_padding)
2980    else:
2981      raise ValueError(
2982          '`padding` should be either an int, '
2983          'a tuple of 3 ints '
2984          '(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad), '
2985          'or a tuple of 3 tuples of 2 ints '
2986          '((left_dim1_pad, right_dim1_pad),'
2987          ' (left_dim2_pad, right_dim2_pad),'
2988          ' (left_dim3_pad, right_dim2_pad)). '
2989          'Found: ' + str(padding))
2990    self.input_spec = InputSpec(ndim=5)
2991
2992  def compute_output_shape(self, input_shape):
2993    input_shape = tensor_shape.TensorShape(input_shape).as_list()
2994    if self.data_format == 'channels_first':
2995      if input_shape[2] is not None:
2996        dim1 = input_shape[2] + self.padding[0][0] + self.padding[0][1]
2997      else:
2998        dim1 = None
2999      if input_shape[3] is not None:
3000        dim2 = input_shape[3] + self.padding[1][0] + self.padding[1][1]
3001      else:
3002        dim2 = None
3003      if input_shape[4] is not None:
3004        dim3 = input_shape[4] + self.padding[2][0] + self.padding[2][1]
3005      else:
3006        dim3 = None
3007      return tensor_shape.TensorShape(
3008          [input_shape[0], input_shape[1], dim1, dim2, dim3])
3009    elif self.data_format == 'channels_last':
3010      if input_shape[1] is not None:
3011        dim1 = input_shape[1] + self.padding[0][0] + self.padding[0][1]
3012      else:
3013        dim1 = None
3014      if input_shape[2] is not None:
3015        dim2 = input_shape[2] + self.padding[1][0] + self.padding[1][1]
3016      else:
3017        dim2 = None
3018      if input_shape[3] is not None:
3019        dim3 = input_shape[3] + self.padding[2][0] + self.padding[2][1]
3020      else:
3021        dim3 = None
3022      return tensor_shape.TensorShape(
3023          [input_shape[0], dim1, dim2, dim3, input_shape[4]])
3024
3025  def call(self, inputs):
3026    return backend.spatial_3d_padding(
3027        inputs, padding=self.padding, data_format=self.data_format)
3028
3029  def get_config(self):
3030    config = {'padding': self.padding, 'data_format': self.data_format}
3031    base_config = super(ZeroPadding3D, self).get_config()
3032    return dict(list(base_config.items()) + list(config.items()))
3033
3034
3035@keras_export('keras.layers.Cropping1D')
3036class Cropping1D(Layer):
3037  """Cropping layer for 1D input (e.g. temporal sequence).
3038
3039  It crops along the time dimension (axis 1).
3040
3041  Examples:
3042
3043  >>> input_shape = (2, 3, 2)
3044  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
3045  >>> print(x)
3046  [[[ 0  1]
3047    [ 2  3]
3048    [ 4  5]]
3049   [[ 6  7]
3050    [ 8  9]
3051    [10 11]]]
3052  >>> y = tf.keras.layers.Cropping1D(cropping=1)(x)
3053  >>> print(y)
3054  tf.Tensor(
3055    [[[2 3]]
3056     [[8 9]]], shape=(2, 1, 2), dtype=int64)
3057
3058  Args:
3059    cropping: Int or tuple of int (length 2)
3060      How many units should be trimmed off at the beginning and end of
3061      the cropping dimension (axis 1).
3062      If a single int is provided, the same value will be used for both.
3063
3064  Input shape:
3065    3D tensor with shape `(batch_size, axis_to_crop, features)`
3066
3067  Output shape:
3068    3D tensor with shape `(batch_size, cropped_axis, features)`
3069  """
3070
3071  def __init__(self, cropping=(1, 1), **kwargs):
3072    super(Cropping1D, self).__init__(**kwargs)
3073    self.cropping = conv_utils.normalize_tuple(cropping, 2, 'cropping')
3074    self.input_spec = InputSpec(ndim=3)
3075
3076  def compute_output_shape(self, input_shape):
3077    input_shape = tensor_shape.TensorShape(input_shape).as_list()
3078    if input_shape[1] is not None:
3079      length = input_shape[1] - self.cropping[0] - self.cropping[1]
3080    else:
3081      length = None
3082    return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]])
3083
3084  def call(self, inputs):
3085    if self.cropping[1] == 0:
3086      return inputs[:, self.cropping[0]:, :]
3087    else:
3088      return inputs[:, self.cropping[0]:-self.cropping[1], :]
3089
3090  def get_config(self):
3091    config = {'cropping': self.cropping}
3092    base_config = super(Cropping1D, self).get_config()
3093    return dict(list(base_config.items()) + list(config.items()))
3094
3095
3096@keras_export('keras.layers.Cropping2D')
3097class Cropping2D(Layer):
3098  """Cropping layer for 2D input (e.g. picture).
3099
3100  It crops along spatial dimensions, i.e. height and width.
3101
3102  Examples:
3103
3104  >>> input_shape = (2, 28, 28, 3)
3105  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
3106  >>> y = tf.keras.layers.Cropping2D(cropping=((2, 2), (4, 4)))(x)
3107  >>> print(y.shape)
3108  (2, 24, 20, 3)
3109
3110  Args:
3111    cropping: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
3112      - If int: the same symmetric cropping
3113        is applied to height and width.
3114      - If tuple of 2 ints:
3115        interpreted as two different
3116        symmetric cropping values for height and width:
3117        `(symmetric_height_crop, symmetric_width_crop)`.
3118      - If tuple of 2 tuples of 2 ints:
3119        interpreted as
3120        `((top_crop, bottom_crop), (left_crop, right_crop))`
3121    data_format: A string,
3122      one of `channels_last` (default) or `channels_first`.
3123      The ordering of the dimensions in the inputs.
3124      `channels_last` corresponds to inputs with shape
3125      `(batch_size, height, width, channels)` while `channels_first`
3126      corresponds to inputs with shape
3127      `(batch_size, channels, height, width)`.
3128      It defaults to the `image_data_format` value found in your
3129      Keras config file at `~/.keras/keras.json`.
3130      If you never set it, then it will be "channels_last".
3131
3132  Input shape:
3133    4D tensor with shape:
3134    - If `data_format` is `"channels_last"`:
3135      `(batch_size, rows, cols, channels)`
3136    - If `data_format` is `"channels_first"`:
3137      `(batch_size, channels, rows, cols)`
3138
3139  Output shape:
3140    4D tensor with shape:
3141    - If `data_format` is `"channels_last"`:
3142      `(batch_size, cropped_rows, cropped_cols, channels)`
3143    - If `data_format` is `"channels_first"`:
3144      `(batch_size, channels, cropped_rows, cropped_cols)`
3145  """
3146
3147  def __init__(self, cropping=((0, 0), (0, 0)), data_format=None, **kwargs):
3148    super(Cropping2D, self).__init__(**kwargs)
3149    self.data_format = conv_utils.normalize_data_format(data_format)
3150    if isinstance(cropping, int):
3151      self.cropping = ((cropping, cropping), (cropping, cropping))
3152    elif hasattr(cropping, '__len__'):
3153      if len(cropping) != 2:
3154        raise ValueError('`cropping` should have two elements. '
3155                         'Found: ' + str(cropping))
3156      height_cropping = conv_utils.normalize_tuple(cropping[0], 2,
3157                                                   '1st entry of cropping')
3158      width_cropping = conv_utils.normalize_tuple(cropping[1], 2,
3159                                                  '2nd entry of cropping')
3160      self.cropping = (height_cropping, width_cropping)
3161    else:
3162      raise ValueError('`cropping` should be either an int, '
3163                       'a tuple of 2 ints '
3164                       '(symmetric_height_crop, symmetric_width_crop), '
3165                       'or a tuple of 2 tuples of 2 ints '
3166                       '((top_crop, bottom_crop), (left_crop, right_crop)). '
3167                       'Found: ' + str(cropping))
3168    self.input_spec = InputSpec(ndim=4)
3169
3170  def compute_output_shape(self, input_shape):
3171    input_shape = tensor_shape.TensorShape(input_shape).as_list()
3172    # pylint: disable=invalid-unary-operand-type
3173    if self.data_format == 'channels_first':
3174      return tensor_shape.TensorShape([
3175          input_shape[0], input_shape[1],
3176          input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
3177          if input_shape[2] else None,
3178          input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
3179          if input_shape[3] else None
3180      ])
3181    else:
3182      return tensor_shape.TensorShape([
3183          input_shape[0],
3184          input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
3185          if input_shape[1] else None,
3186          input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
3187          if input_shape[2] else None, input_shape[3]
3188      ])
3189    # pylint: enable=invalid-unary-operand-type
3190
3191  def call(self, inputs):
3192    # pylint: disable=invalid-unary-operand-type
3193    if self.data_format == 'channels_first':
3194      if self.cropping[0][1] == self.cropping[1][1] == 0:
3195        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:]
3196      elif self.cropping[0][1] == 0:
3197        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
3198                      -self.cropping[1][1]]
3199      elif self.cropping[1][1] == 0:
3200        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
3201                      self.cropping[1][0]:]
3202      return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
3203                    self.cropping[1][0]:-self.cropping[1][1]]
3204    else:
3205      if self.cropping[0][1] == self.cropping[1][1] == 0:
3206        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, :]
3207      elif self.cropping[0][1] == 0:
3208        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
3209                      -self.cropping[1][1], :]
3210      elif self.cropping[1][1] == 0:
3211        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
3212                      self.cropping[1][0]:, :]
3213      return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
3214          1][0]:-self.cropping[1][1], :]  # pylint: disable=invalid-unary-operand-type
3215    # pylint: enable=invalid-unary-operand-type
3216
3217  def get_config(self):
3218    config = {'cropping': self.cropping, 'data_format': self.data_format}
3219    base_config = super(Cropping2D, self).get_config()
3220    return dict(list(base_config.items()) + list(config.items()))
3221
3222
3223@keras_export('keras.layers.Cropping3D')
3224class Cropping3D(Layer):
3225  """Cropping layer for 3D data (e.g. spatial or spatio-temporal).
3226
3227    Examples:
3228
3229  >>> input_shape = (2, 28, 28, 10, 3)
3230  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
3231  >>> y = tf.keras.layers.Cropping3D(cropping=(2, 4, 2))(x)
3232  >>> print(y.shape)
3233  (2, 24, 20, 6, 3)
3234
3235  Args:
3236    cropping: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints.
3237      - If int: the same symmetric cropping
3238        is applied to depth, height, and width.
3239      - If tuple of 3 ints: interpreted as two different
3240        symmetric cropping values for depth, height, and width:
3241        `(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop)`.
3242      - If tuple of 3 tuples of 2 ints: interpreted as
3243        `((left_dim1_crop, right_dim1_crop), (left_dim2_crop,
3244          right_dim2_crop), (left_dim3_crop, right_dim3_crop))`
3245    data_format: A string,
3246      one of `channels_last` (default) or `channels_first`.
3247      The ordering of the dimensions in the inputs.
3248      `channels_last` corresponds to inputs with shape
3249      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
3250      while `channels_first` corresponds to inputs with shape
3251      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
3252      It defaults to the `image_data_format` value found in your
3253      Keras config file at `~/.keras/keras.json`.
3254      If you never set it, then it will be "channels_last".
3255
3256  Input shape:
3257    5D tensor with shape:
3258    - If `data_format` is `"channels_last"`:
3259      `(batch_size, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop,
3260        depth)`
3261    - If `data_format` is `"channels_first"`:
3262      `(batch_size, depth, first_axis_to_crop, second_axis_to_crop,
3263        third_axis_to_crop)`
3264
3265  Output shape:
3266    5D tensor with shape:
3267    - If `data_format` is `"channels_last"`:
3268      `(batch_size, first_cropped_axis, second_cropped_axis, third_cropped_axis,
3269        depth)`
3270    - If `data_format` is `"channels_first"`:
3271      `(batch_size, depth, first_cropped_axis, second_cropped_axis,
3272        third_cropped_axis)`
3273  """
3274
3275  def __init__(self,
3276               cropping=((1, 1), (1, 1), (1, 1)),
3277               data_format=None,
3278               **kwargs):
3279    super(Cropping3D, self).__init__(**kwargs)
3280    self.data_format = conv_utils.normalize_data_format(data_format)
3281    if isinstance(cropping, int):
3282      self.cropping = ((cropping, cropping), (cropping, cropping), (cropping,
3283                                                                    cropping))
3284    elif hasattr(cropping, '__len__'):
3285      if len(cropping) != 3:
3286        raise ValueError('`cropping` should have 3 elements. '
3287                         'Found: ' + str(cropping))
3288      dim1_cropping = conv_utils.normalize_tuple(cropping[0], 2,
3289                                                 '1st entry of cropping')
3290      dim2_cropping = conv_utils.normalize_tuple(cropping[1], 2,
3291                                                 '2nd entry of cropping')
3292      dim3_cropping = conv_utils.normalize_tuple(cropping[2], 2,
3293                                                 '3rd entry of cropping')
3294      self.cropping = (dim1_cropping, dim2_cropping, dim3_cropping)
3295    else:
3296      raise ValueError(
3297          '`cropping` should be either an int, '
3298          'a tuple of 3 ints '
3299          '(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop), '
3300          'or a tuple of 3 tuples of 2 ints '
3301          '((left_dim1_crop, right_dim1_crop),'
3302          ' (left_dim2_crop, right_dim2_crop),'
3303          ' (left_dim3_crop, right_dim2_crop)). '
3304          'Found: ' + str(cropping))
3305    self.input_spec = InputSpec(ndim=5)
3306
3307  def compute_output_shape(self, input_shape):
3308    input_shape = tensor_shape.TensorShape(input_shape).as_list()
3309    # pylint: disable=invalid-unary-operand-type
3310    if self.data_format == 'channels_first':
3311      if input_shape[2] is not None:
3312        dim1 = input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
3313      else:
3314        dim1 = None
3315      if input_shape[3] is not None:
3316        dim2 = input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
3317      else:
3318        dim2 = None
3319      if input_shape[4] is not None:
3320        dim3 = input_shape[4] - self.cropping[2][0] - self.cropping[2][1]
3321      else:
3322        dim3 = None
3323      return tensor_shape.TensorShape(
3324          [input_shape[0], input_shape[1], dim1, dim2, dim3])
3325    elif self.data_format == 'channels_last':
3326      if input_shape[1] is not None:
3327        dim1 = input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
3328      else:
3329        dim1 = None
3330      if input_shape[2] is not None:
3331        dim2 = input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
3332      else:
3333        dim2 = None
3334      if input_shape[3] is not None:
3335        dim3 = input_shape[3] - self.cropping[2][0] - self.cropping[2][1]
3336      else:
3337        dim3 = None
3338      return tensor_shape.TensorShape(
3339          [input_shape[0], dim1, dim2, dim3, input_shape[4]])
3340    # pylint: enable=invalid-unary-operand-type
3341
3342  def call(self, inputs):
3343    # pylint: disable=invalid-unary-operand-type
3344    if self.data_format == 'channels_first':
3345      if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
3346        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
3347                      self.cropping[2][0]:]
3348      elif self.cropping[0][1] == self.cropping[1][1] == 0:
3349        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
3350                      self.cropping[2][0]:-self.cropping[2][1]]
3351      elif self.cropping[1][1] == self.cropping[2][1] == 0:
3352        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
3353                      self.cropping[1][0]:, self.cropping[2][0]:]
3354      elif self.cropping[0][1] == self.cropping[2][1] == 0:
3355        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
3356                      -self.cropping[1][1], self.cropping[2][0]:]
3357      elif self.cropping[0][1] == 0:
3358        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][
3359            0]:-self.cropping[1][1], self.cropping[2][0]:-self.cropping[2][1]]
3360      elif self.cropping[1][1] == 0:
3361        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
3362                      cropping[1][0]:, self.cropping[2][0]:-self.cropping[2][1]]
3363      elif self.cropping[2][1] == 0:
3364        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
3365                      cropping[1][0]:-self.cropping[1][1], self.cropping[2][0]:]
3366      return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
3367                    self.cropping[1][0]:-self.cropping[1][1], self.cropping[2][
3368                        0]:-self.cropping[2][1]]
3369    else:
3370      if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
3371        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
3372                      self.cropping[2][0]:, :]
3373      elif self.cropping[0][1] == self.cropping[1][1] == 0:
3374        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
3375                      self.cropping[2][0]:-self.cropping[2][1], :]
3376      elif self.cropping[1][1] == self.cropping[2][1] == 0:
3377        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
3378                      self.cropping[1][0]:, self.cropping[2][0]:, :]
3379      elif self.cropping[0][1] == self.cropping[2][1] == 0:
3380        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
3381                      -self.cropping[1][1], self.cropping[2][0]:, :]
3382      elif self.cropping[0][1] == 0:
3383        return inputs[:, self.cropping[0][0]:, self.cropping[1][
3384            0]:-self.cropping[1][1], self.cropping[2][0]:
3385                      -self.cropping[2][1], :]
3386      elif self.cropping[1][1] == 0:
3387        return inputs[:, self.cropping[0][
3388            0]:-self.cropping[0][1], self.cropping[1][0]:, self.cropping[2][0]:
3389                      -self.cropping[2][1], :]
3390      elif self.cropping[2][1] == 0:
3391        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
3392                      self.cropping[1][0]:-self.cropping[1][1], self.cropping[
3393                          2][0]:, :]
3394      return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
3395          1][0]:-self.cropping[1][1], self.cropping[2][0]:  # pylint: disable=invalid-unary-operand-type
3396                    -self.cropping[2][1], :]  # pylint: disable=invalid-unary-operand-type
3397    # pylint: enable=invalid-unary-operand-type
3398
3399  def get_config(self):
3400    config = {'cropping': self.cropping, 'data_format': self.data_format}
3401    base_config = super(Cropping3D, self).get_config()
3402    return dict(list(base_config.items()) + list(config.items()))
3403
3404
3405# Aliases
3406
3407Convolution1D = Conv1D
3408Convolution2D = Conv2D
3409Convolution3D = Conv3D
3410SeparableConvolution1D = SeparableConv1D
3411SeparableConvolution2D = SeparableConv2D
3412Convolution2DTranspose = Conv2DTranspose
3413Convolution3DTranspose = Conv3DTranspose
3414Deconvolution2D = Deconv2D = Conv2DTranspose
3415Deconvolution3D = Deconv3D = Conv3DTranspose
3416