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