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