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