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