Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/keras/layers/convolutional.py: 18%

820 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================== 

15"""Keras convolution layers and image transformation layers.""" 

16 

17import functools 

18 

19from tensorflow.python.eager import context 

20from tensorflow.python.framework import tensor_shape 

21from tensorflow.python.keras import activations 

22from tensorflow.python.keras import backend 

23from tensorflow.python.keras import constraints 

24from tensorflow.python.keras import initializers 

25from tensorflow.python.keras import regularizers 

26from tensorflow.python.keras.engine.base_layer import Layer 

27from tensorflow.python.keras.engine.input_spec import InputSpec 

28# imports for backwards namespace compatibility 

29# pylint: disable=unused-import 

30from tensorflow.python.keras.layers.pooling import AveragePooling1D 

31from tensorflow.python.keras.layers.pooling import AveragePooling2D 

32from tensorflow.python.keras.layers.pooling import AveragePooling3D 

33from tensorflow.python.keras.layers.pooling import MaxPooling1D 

34from tensorflow.python.keras.layers.pooling import MaxPooling2D 

35from tensorflow.python.keras.layers.pooling import MaxPooling3D 

36# pylint: enable=unused-import 

37from tensorflow.python.keras.utils import conv_utils 

38from tensorflow.python.keras.utils import tf_utils 

39from tensorflow.python.ops import array_ops 

40from tensorflow.python.ops import array_ops_stack 

41from tensorflow.python.ops import nn 

42from tensorflow.python.ops import nn_ops 

43from tensorflow.python.util.tf_export import keras_export 

44# pylint: disable=g-classes-have-attributes 

45 

46 

47class Conv(Layer): 

48 """Abstract N-D convolution layer (private, used as implementation base). 

49 

50 This layer creates a convolution kernel that is convolved 

51 (actually cross-correlated) with the layer input to produce a tensor of 

52 outputs. If `use_bias` is True (and a `bias_initializer` is provided), 

53 a bias vector is created and added to the outputs. Finally, if 

54 `activation` is not `None`, it is applied to the outputs as well. 

55 

56 Note: layer attributes cannot be modified after the layer has been called 

57 once (except the `trainable` attribute). 

58 

59 Args: 

60 rank: An integer, the rank of the convolution, e.g. "2" for 2D convolution. 

61 filters: Integer, the dimensionality of the output space (i.e. the number 

62 of filters in the convolution). Could be "None", eg in the case of 

63 depth wise convolution. 

64 kernel_size: An integer or tuple/list of n integers, specifying the 

65 length of the convolution window. 

66 strides: An integer or tuple/list of n integers, 

67 specifying the stride length of the convolution. 

68 Specifying any stride value != 1 is incompatible with specifying 

69 any `dilation_rate` value != 1. 

70 padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive). 

71 `"valid"` means no padding. `"same"` results in padding with zeros 

72 evenly to the left/right or up/down of the input such that output has the 

73 same height/width dimension as the input. `"causal"` results in causal 

74 (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`. 

75 data_format: A string, one of `channels_last` (default) or `channels_first`. 

76 The ordering of the dimensions in the inputs. 

77 `channels_last` corresponds to inputs with shape 

78 `(batch_size, ..., channels)` while `channels_first` corresponds to 

79 inputs with shape `(batch_size, channels, ...)`. 

80 Note: `channels_first` is only available on GPUs. 

81 dilation_rate: An integer or tuple/list of n integers, specifying 

82 the dilation rate to use for dilated convolution. 

83 Currently, specifying any `dilation_rate` value != 1 is 

84 incompatible with specifying any `strides` value != 1. 

85 groups: A positive integer specifying the number of groups in which the 

86 input is split along the channel axis. Each group is convolved 

87 separately with `filters / groups` filters. The output is the 

88 concatenation of all the `groups` results along the channel axis. 

89 Input channels and `filters` must both be divisible by `groups`. 

90 activation: Activation function to use. 

91 If you don't specify anything, no activation is applied. 

92 use_bias: Boolean, whether the layer uses a bias. 

93 kernel_initializer: An initializer for the convolution kernel. If None, the  

94 default initializer (glorot_uniform) will be used.  

95 bias_initializer: An initializer for the bias vector. If None, the default 

96 initializer (zeros) will be used. 

97 kernel_regularizer: Optional regularizer for the convolution kernel. 

98 bias_regularizer: Optional regularizer for the bias vector. 

99 activity_regularizer: Optional regularizer function for the output. 

100 kernel_constraint: Optional projection function to be applied to the 

101 kernel after being updated by an `Optimizer` (e.g. used to implement 

102 norm constraints or value constraints for layer weights). The function 

103 must take as input the unprojected variable and must return the 

104 projected variable (which must have the same shape). Constraints are 

105 not safe to use when doing asynchronous distributed training. 

106 bias_constraint: Optional projection function to be applied to the 

107 bias after being updated by an `Optimizer`. 

108 """ 

109 

110 def __init__(self, 

111 rank, 

112 filters, 

113 kernel_size, 

114 strides=1, 

115 padding='valid', 

116 data_format=None, 

117 dilation_rate=1, 

118 groups=1, 

119 activation=None, 

120 use_bias=True, 

121 kernel_initializer='glorot_uniform', 

122 bias_initializer='zeros', 

123 kernel_regularizer=None, 

124 bias_regularizer=None, 

125 activity_regularizer=None, 

126 kernel_constraint=None, 

127 bias_constraint=None, 

128 trainable=True, 

129 name=None, 

130 conv_op=None, 

131 **kwargs): 

132 super(Conv, self).__init__( 

133 trainable=trainable, 

134 name=name, 

135 activity_regularizer=regularizers.get(activity_regularizer), 

136 **kwargs) 

137 self.rank = rank 

138 

139 if isinstance(filters, float): 

140 filters = int(filters) 

141 if filters is not None and filters < 0: 

142 raise ValueError(f'Received a negative value for `filters`.' 

143 f'Was expecting a positive value, got {filters}.') 

144 self.filters = filters 

145 self.groups = groups or 1 

146 self.kernel_size = conv_utils.normalize_tuple( 

147 kernel_size, rank, 'kernel_size') 

148 self.strides = conv_utils.normalize_tuple(strides, rank, 'strides') 

149 self.padding = conv_utils.normalize_padding(padding) 

150 self.data_format = conv_utils.normalize_data_format(data_format) 

151 self.dilation_rate = conv_utils.normalize_tuple( 

152 dilation_rate, rank, 'dilation_rate') 

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 not all(self.strides): 

183 raise ValueError('The argument `strides` cannot contains 0(s). ' 

184 'Received: %s' % (self.strides,)) 

185 

186 if (self.padding == 'causal' and not isinstance(self, 

187 (Conv1D, SeparableConv1D))): 

188 raise ValueError('Causal padding is only supported for `Conv1D`' 

189 'and `SeparableConv1D`.') 

190 

191 def build(self, input_shape): 

192 input_shape = tensor_shape.TensorShape(input_shape) 

193 input_channel = self._get_input_channel(input_shape) 

194 if input_channel % self.groups != 0: 

195 raise ValueError( 

196 'The number of input channels must be evenly divisible by the number ' 

197 'of groups. Received groups={}, but the input has {} channels ' 

198 '(full input shape is {}).'.format(self.groups, input_channel, 

199 input_shape)) 

200 kernel_shape = self.kernel_size + (input_channel // self.groups, 

201 self.filters) 

202 

203 self.kernel = self.add_weight( 

204 name='kernel', 

205 shape=kernel_shape, 

206 initializer=self.kernel_initializer, 

207 regularizer=self.kernel_regularizer, 

208 constraint=self.kernel_constraint, 

209 trainable=True, 

210 dtype=self.dtype) 

211 if self.use_bias: 

212 self.bias = self.add_weight( 

213 name='bias', 

214 shape=(self.filters,), 

215 initializer=self.bias_initializer, 

216 regularizer=self.bias_regularizer, 

217 constraint=self.bias_constraint, 

218 trainable=True, 

219 dtype=self.dtype) 

220 else: 

221 self.bias = None 

222 channel_axis = self._get_channel_axis() 

223 self.input_spec = InputSpec(min_ndim=self.rank + 2, 

224 axes={channel_axis: input_channel}) 

225 

226 # Convert Keras formats to TF native formats. 

227 if self.padding == 'causal': 

228 tf_padding = 'VALID' # Causal padding handled in `call`. 

229 elif isinstance(self.padding, str): 

230 tf_padding = self.padding.upper() 

231 else: 

232 tf_padding = self.padding 

233 tf_dilations = list(self.dilation_rate) 

234 tf_strides = list(self.strides) 

235 

236 tf_op_name = self.__class__.__name__ 

237 if tf_op_name == 'Conv1D': 

238 tf_op_name = 'conv1d' # Backwards compat. 

239 

240 self._convolution_op = functools.partial( 

241 nn_ops.convolution_v2, 

242 strides=tf_strides, 

243 padding=tf_padding, 

244 dilations=tf_dilations, 

245 data_format=self._tf_data_format, 

246 name=tf_op_name) 

247 self.built = True 

248 

249 def call(self, inputs): 

250 input_shape = inputs.shape 

251 

252 if self._is_causal: # Apply causal padding to inputs for Conv1D. 

253 inputs = array_ops.pad(inputs, self._compute_causal_padding(inputs)) 

254 

255 outputs = self._convolution_op(inputs, self.kernel) 

256 

257 if self.use_bias: 

258 output_rank = outputs.shape.rank 

259 if self.rank == 1 and self._channels_first: 

260 # nn.bias_add does not accept a 1D input tensor. 

261 bias = array_ops.reshape(self.bias, (1, self.filters, 1)) 

262 outputs += bias 

263 else: 

264 # Handle multiple batch dimensions. 

265 if output_rank is not None and output_rank > 2 + self.rank: 

266 

267 def _apply_fn(o): 

268 return nn.bias_add(o, self.bias, data_format=self._tf_data_format) 

269 

270 outputs = conv_utils.squeeze_batch_dims( 

271 outputs, _apply_fn, inner_rank=self.rank + 1) 

272 else: 

273 outputs = nn.bias_add( 

274 outputs, self.bias, data_format=self._tf_data_format) 

275 

276 if not context.executing_eagerly(): 

277 # Infer the static output shape: 

278 out_shape = self.compute_output_shape(input_shape) 

279 outputs.set_shape(out_shape) 

280 

281 if self.activation is not None: 

282 return self.activation(outputs) 

283 return outputs 

284 

285 def _spatial_output_shape(self, spatial_input_shape): 

286 return [ 

287 conv_utils.conv_output_length( 

288 length, 

289 self.kernel_size[i], 

290 padding=self.padding, 

291 stride=self.strides[i], 

292 dilation=self.dilation_rate[i]) 

293 for i, length in enumerate(spatial_input_shape) 

294 ] 

295 

296 def compute_output_shape(self, input_shape): 

297 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

298 batch_rank = len(input_shape) - self.rank - 1 

299 if self.data_format == 'channels_last': 

300 return tensor_shape.TensorShape( 

301 input_shape[:batch_rank] 

302 + self._spatial_output_shape(input_shape[batch_rank:-1]) 

303 + [self.filters]) 

304 else: 

305 return tensor_shape.TensorShape( 

306 input_shape[:batch_rank] + [self.filters] + 

307 self._spatial_output_shape(input_shape[batch_rank + 1:])) 

308 

309 def _recreate_conv_op(self, inputs): # pylint: disable=unused-argument 

310 return False 

311 

312 def get_config(self): 

313 config = { 

314 'filters': 

315 self.filters, 

316 'kernel_size': 

317 self.kernel_size, 

318 'strides': 

319 self.strides, 

320 'padding': 

321 self.padding, 

322 'data_format': 

323 self.data_format, 

324 'dilation_rate': 

325 self.dilation_rate, 

326 'groups': 

327 self.groups, 

328 'activation': 

329 activations.serialize(self.activation), 

330 'use_bias': 

331 self.use_bias, 

332 'kernel_initializer': 

333 initializers.serialize(self.kernel_initializer), 

334 'bias_initializer': 

335 initializers.serialize(self.bias_initializer), 

336 'kernel_regularizer': 

337 regularizers.serialize(self.kernel_regularizer), 

338 'bias_regularizer': 

339 regularizers.serialize(self.bias_regularizer), 

340 'activity_regularizer': 

341 regularizers.serialize(self.activity_regularizer), 

342 'kernel_constraint': 

343 constraints.serialize(self.kernel_constraint), 

344 'bias_constraint': 

345 constraints.serialize(self.bias_constraint) 

346 } 

347 base_config = super(Conv, self).get_config() 

348 return dict(list(base_config.items()) + list(config.items())) 

349 

350 def _compute_causal_padding(self, inputs): 

351 """Calculates padding for 'causal' option for 1-d conv layers.""" 

352 left_pad = self.dilation_rate[0] * (self.kernel_size[0] - 1) 

353 if getattr(inputs.shape, 'ndims', None) is None: 

354 batch_rank = 1 

355 else: 

356 batch_rank = len(inputs.shape) - 2 

357 if self.data_format == 'channels_last': 

358 causal_padding = [[0, 0]] * batch_rank + [[left_pad, 0], [0, 0]] 

359 else: 

360 causal_padding = [[0, 0]] * batch_rank + [[0, 0], [left_pad, 0]] 

361 return causal_padding 

362 

363 def _get_channel_axis(self): 

364 if self.data_format == 'channels_first': 

365 return -1 - self.rank 

366 else: 

367 return -1 

368 

369 def _get_input_channel(self, input_shape): 

370 channel_axis = self._get_channel_axis() 

371 if input_shape.dims[channel_axis].value is None: 

372 raise ValueError('The channel dimension of the inputs ' 

373 'should be defined. Found `None`.') 

374 return int(input_shape[channel_axis]) 

375 

376 def _get_padding_op(self): 

377 if self.padding == 'causal': 

378 op_padding = 'valid' 

379 else: 

380 op_padding = self.padding 

381 if not isinstance(op_padding, (list, tuple)): 

382 op_padding = op_padding.upper() 

383 return op_padding 

384 

385 

386@keras_export('keras.layers.Conv1D', 'keras.layers.Convolution1D') 

387class Conv1D(Conv): 

388 """1D convolution layer (e.g. temporal convolution). 

389 

390 This layer creates a convolution kernel that is convolved 

391 with the layer input over a single spatial (or temporal) dimension 

392 to produce a tensor of outputs. 

393 If `use_bias` is True, a bias vector is created and added to the outputs. 

394 Finally, if `activation` is not `None`, 

395 it is applied to the outputs as well. 

396 

397 When using this layer as the first layer in a model, 

398 provide an `input_shape` argument 

399 (tuple of integers or `None`, e.g. 

400 `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors, 

401 or `(None, 128)` for variable-length sequences of 128-dimensional vectors. 

402 

403 Examples: 

404 

405 >>> # The inputs are 128-length vectors with 10 timesteps, and the batch size 

406 >>> # is 4. 

407 >>> input_shape = (4, 10, 128) 

408 >>> x = tf.random.normal(input_shape) 

409 >>> y = tf.keras.layers.Conv1D( 

410 ... 32, 3, activation='relu',input_shape=input_shape[1:])(x) 

411 >>> print(y.shape) 

412 (4, 8, 32) 

413 

414 >>> # With extended batch shape [4, 7] (e.g. weather data where batch 

415 >>> # dimensions correspond to spatial location and the third dimension 

416 >>> # corresponds to time.) 

417 >>> input_shape = (4, 7, 10, 128) 

418 >>> x = tf.random.normal(input_shape) 

419 >>> y = tf.keras.layers.Conv1D( 

420 ... 32, 3, activation='relu', input_shape=input_shape[2:])(x) 

421 >>> print(y.shape) 

422 (4, 7, 8, 32) 

423 

424 Args: 

425 filters: Integer, the dimensionality of the output space 

426 (i.e. the number of output filters in the convolution). 

427 kernel_size: An integer or tuple/list of a single integer, 

428 specifying the length of the 1D convolution window. 

429 strides: An integer or tuple/list of a single integer, 

430 specifying the stride length of the convolution. 

431 Specifying any stride value != 1 is incompatible with specifying 

432 any `dilation_rate` value != 1. 

433 padding: One of `"valid"`, `"same"` or `"causal"` (case-insensitive). 

434 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

435 to the left/right or up/down of the input such that output has the same 

436 height/width dimension as the input. 

437 `"causal"` results in causal (dilated) convolutions, e.g. `output[t]` 

438 does not depend on `input[t+1:]`. Useful when modeling temporal data 

439 where the model should not violate the temporal order. 

440 See [WaveNet: A Generative Model for Raw Audio, section 

441 2.1](https://arxiv.org/abs/1609.03499). 

442 data_format: A string, 

443 one of `channels_last` (default) or `channels_first`. 

444 dilation_rate: an integer or tuple/list of a single integer, specifying 

445 the dilation rate to use for dilated convolution. 

446 Currently, specifying any `dilation_rate` value != 1 is 

447 incompatible with specifying any `strides` value != 1. 

448 groups: A positive integer specifying the number of groups in which the 

449 input is split along the channel axis. Each group is convolved 

450 separately with `filters / groups` filters. The output is the 

451 concatenation of all the `groups` results along the channel axis. 

452 Input channels and `filters` must both be divisible by `groups`. 

453 activation: Activation function to use. 

454 If you don't specify anything, no activation is applied ( 

455 see `keras.activations`). 

456 use_bias: Boolean, whether the layer uses a bias vector. 

457 kernel_initializer: Initializer for the `kernel` weights matrix ( 

458 see `keras.initializers`). Defaults to 'glorot_uniform'. 

459 bias_initializer: Initializer for the bias vector ( 

460 see `keras.initializers`). Defaults to 'zeros'. 

461 kernel_regularizer: Regularizer function applied to 

462 the `kernel` weights matrix (see `keras.regularizers`). 

463 bias_regularizer: Regularizer function applied to the bias vector ( 

464 see `keras.regularizers`). 

465 activity_regularizer: Regularizer function applied to 

466 the output of the layer (its "activation") ( 

467 see `keras.regularizers`). 

468 kernel_constraint: Constraint function applied to the kernel matrix ( 

469 see `keras.constraints`). 

470 bias_constraint: Constraint function applied to the bias vector ( 

471 see `keras.constraints`). 

472 

473 Input shape: 

474 3+D tensor with shape: `batch_shape + (steps, input_dim)` 

475 

476 Output shape: 

477 3+D tensor with shape: `batch_shape + (new_steps, filters)` 

478 `steps` value might have changed due to padding or strides. 

479 

480 Returns: 

481 A tensor of rank 3 representing 

482 `activation(conv1d(inputs, kernel) + bias)`. 

483 

484 Raises: 

485 ValueError: when both `strides > 1` and `dilation_rate > 1`. 

486 """ 

487 

488 def __init__(self, 

489 filters, 

490 kernel_size, 

491 strides=1, 

492 padding='valid', 

493 data_format='channels_last', 

494 dilation_rate=1, 

495 groups=1, 

496 activation=None, 

497 use_bias=True, 

498 kernel_initializer='glorot_uniform', 

499 bias_initializer='zeros', 

500 kernel_regularizer=None, 

501 bias_regularizer=None, 

502 activity_regularizer=None, 

503 kernel_constraint=None, 

504 bias_constraint=None, 

505 **kwargs): 

506 super(Conv1D, self).__init__( 

507 rank=1, 

508 filters=filters, 

509 kernel_size=kernel_size, 

510 strides=strides, 

511 padding=padding, 

512 data_format=data_format, 

513 dilation_rate=dilation_rate, 

514 groups=groups, 

515 activation=activations.get(activation), 

516 use_bias=use_bias, 

517 kernel_initializer=initializers.get(kernel_initializer), 

518 bias_initializer=initializers.get(bias_initializer), 

519 kernel_regularizer=regularizers.get(kernel_regularizer), 

520 bias_regularizer=regularizers.get(bias_regularizer), 

521 activity_regularizer=regularizers.get(activity_regularizer), 

522 kernel_constraint=constraints.get(kernel_constraint), 

523 bias_constraint=constraints.get(bias_constraint), 

524 **kwargs) 

525 

526 

527@keras_export('keras.layers.Conv2D', 'keras.layers.Convolution2D') 

528class Conv2D(Conv): 

529 """2D convolution layer (e.g. spatial convolution over images). 

530 

531 This layer creates a convolution kernel that is convolved 

532 with the layer input to produce a tensor of 

533 outputs. If `use_bias` is True, 

534 a bias vector is created and added to the outputs. Finally, if 

535 `activation` is not `None`, it is applied to the outputs as well. 

536 

537 When using this layer as the first layer in a model, 

538 provide the keyword argument `input_shape` 

539 (tuple of integers or `None`, does not include the sample axis), 

540 e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures 

541 in `data_format="channels_last"`. You can use `None` when 

542 a dimension has variable size. 

543 

544 Examples: 

545 

546 >>> # The inputs are 28x28 RGB images with `channels_last` and the batch 

547 >>> # size is 4. 

548 >>> input_shape = (4, 28, 28, 3) 

549 >>> x = tf.random.normal(input_shape) 

550 >>> y = tf.keras.layers.Conv2D( 

551 ... 2, 3, activation='relu', input_shape=input_shape[1:])(x) 

552 >>> print(y.shape) 

553 (4, 26, 26, 2) 

554 

555 >>> # With `dilation_rate` as 2. 

556 >>> input_shape = (4, 28, 28, 3) 

557 >>> x = tf.random.normal(input_shape) 

558 >>> y = tf.keras.layers.Conv2D( 

559 ... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x) 

560 >>> print(y.shape) 

561 (4, 24, 24, 2) 

562 

563 >>> # With `padding` as "same". 

564 >>> input_shape = (4, 28, 28, 3) 

565 >>> x = tf.random.normal(input_shape) 

566 >>> y = tf.keras.layers.Conv2D( 

567 ... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x) 

568 >>> print(y.shape) 

569 (4, 28, 28, 2) 

570 

571 >>> # With extended batch shape [4, 7]: 

572 >>> input_shape = (4, 7, 28, 28, 3) 

573 >>> x = tf.random.normal(input_shape) 

574 >>> y = tf.keras.layers.Conv2D( 

575 ... 2, 3, activation='relu', input_shape=input_shape[2:])(x) 

576 >>> print(y.shape) 

577 (4, 7, 26, 26, 2) 

578 

579 

580 Args: 

581 filters: Integer, the dimensionality of the output space (i.e. the number of 

582 output filters in the convolution). 

583 kernel_size: An integer or tuple/list of 2 integers, specifying the height 

584 and width of the 2D convolution window. Can be a single integer to specify 

585 the same value for all spatial dimensions. 

586 strides: An integer or tuple/list of 2 integers, specifying the strides of 

587 the convolution along the height and width. Can be a single integer to 

588 specify the same value for all spatial dimensions. Specifying any stride 

589 value != 1 is incompatible with specifying any `dilation_rate` value != 1. 

590 padding: one of `"valid"` or `"same"` (case-insensitive). 

591 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

592 to the left/right or up/down of the input such that output has the same 

593 height/width dimension as the input. 

594 data_format: A string, one of `channels_last` (default) or `channels_first`. 

595 The ordering of the dimensions in the inputs. `channels_last` corresponds 

596 to inputs with shape `(batch_size, height, width, channels)` while 

597 `channels_first` corresponds to inputs with shape `(batch_size, channels, 

598 height, width)`. It defaults to the `image_data_format` value found in 

599 your Keras config file at `~/.keras/keras.json`. If you never set it, then 

600 it will be `channels_last`. 

601 dilation_rate: an integer or tuple/list of 2 integers, specifying the 

602 dilation rate to use for dilated convolution. Can be a single integer to 

603 specify the same value for all spatial dimensions. Currently, specifying 

604 any `dilation_rate` value != 1 is incompatible with specifying any stride 

605 value != 1. 

606 groups: A positive integer specifying the number of groups in which the 

607 input is split along the channel axis. Each group is convolved separately 

608 with `filters / groups` filters. The output is the concatenation of all 

609 the `groups` results along the channel axis. Input channels and `filters` 

610 must both be divisible by `groups`. 

611 activation: Activation function to use. If you don't specify anything, no 

612 activation is applied (see `keras.activations`). 

613 use_bias: Boolean, whether the layer uses a bias vector. 

614 kernel_initializer: Initializer for the `kernel` weights matrix (see 

615 `keras.initializers`). Defaults to 'glorot_uniform'. 

616 bias_initializer: Initializer for the bias vector (see 

617 `keras.initializers`). Defaults to 'zeros'. 

618 kernel_regularizer: Regularizer function applied to the `kernel` weights 

619 matrix (see `keras.regularizers`).  

620 bias_regularizer: Regularizer function applied to the bias vector (see 

621 `keras.regularizers`).  

622 activity_regularizer: Regularizer function applied to the output of the 

623 layer (its "activation") (see `keras.regularizers`). 

624 kernel_constraint: Constraint function applied to the kernel matrix (see 

625 `keras.constraints`). 

626 bias_constraint: Constraint function applied to the bias vector (see 

627 `keras.constraints`). 

628 Input shape: 

629 4+D tensor with shape: `batch_shape + (channels, rows, cols)` if 

630 `data_format='channels_first'` 

631 or 4+D tensor with shape: `batch_shape + (rows, cols, channels)` if 

632 `data_format='channels_last'`. 

633 Output shape: 

634 4+D tensor with shape: `batch_shape + (filters, new_rows, new_cols)` if 

635 `data_format='channels_first'` or 4+D tensor with shape: `batch_shape + 

636 (new_rows, new_cols, filters)` if `data_format='channels_last'`. `rows` 

637 and `cols` values might have changed due to padding. 

638 

639 Returns: 

640 A tensor of rank 4+ representing 

641 `activation(conv2d(inputs, kernel) + bias)`. 

642 

643 Raises: 

644 ValueError: if `padding` is `"causal"`. 

645 ValueError: when both `strides > 1` and `dilation_rate > 1`. 

646 """ 

647 

648 def __init__(self, 

649 filters, 

650 kernel_size, 

651 strides=(1, 1), 

652 padding='valid', 

653 data_format=None, 

654 dilation_rate=(1, 1), 

655 groups=1, 

656 activation=None, 

657 use_bias=True, 

658 kernel_initializer='glorot_uniform', 

659 bias_initializer='zeros', 

660 kernel_regularizer=None, 

661 bias_regularizer=None, 

662 activity_regularizer=None, 

663 kernel_constraint=None, 

664 bias_constraint=None, 

665 **kwargs): 

666 super(Conv2D, self).__init__( 

667 rank=2, 

668 filters=filters, 

669 kernel_size=kernel_size, 

670 strides=strides, 

671 padding=padding, 

672 data_format=data_format, 

673 dilation_rate=dilation_rate, 

674 groups=groups, 

675 activation=activations.get(activation), 

676 use_bias=use_bias, 

677 kernel_initializer=initializers.get(kernel_initializer), 

678 bias_initializer=initializers.get(bias_initializer), 

679 kernel_regularizer=regularizers.get(kernel_regularizer), 

680 bias_regularizer=regularizers.get(bias_regularizer), 

681 activity_regularizer=regularizers.get(activity_regularizer), 

682 kernel_constraint=constraints.get(kernel_constraint), 

683 bias_constraint=constraints.get(bias_constraint), 

684 **kwargs) 

685 

686 

687@keras_export('keras.layers.Conv3D', 'keras.layers.Convolution3D') 

688class Conv3D(Conv): 

689 """3D convolution layer (e.g. spatial convolution over volumes). 

690 

691 This layer creates a convolution kernel that is convolved 

692 with the layer input to produce a tensor of 

693 outputs. If `use_bias` is True, 

694 a bias vector is created and added to the outputs. Finally, if 

695 `activation` is not `None`, it is applied to the outputs as well. 

696 

697 When using this layer as the first layer in a model, 

698 provide the keyword argument `input_shape` 

699 (tuple of integers or `None`, does not include the sample axis), 

700 e.g. `input_shape=(128, 128, 128, 1)` for 128x128x128 volumes 

701 with a single channel, 

702 in `data_format="channels_last"`. 

703 

704 Examples: 

705 

706 >>> # The inputs are 28x28x28 volumes with a single channel, and the 

707 >>> # batch size is 4 

708 >>> input_shape =(4, 28, 28, 28, 1) 

709 >>> x = tf.random.normal(input_shape) 

710 >>> y = tf.keras.layers.Conv3D( 

711 ... 2, 3, activation='relu', input_shape=input_shape[1:])(x) 

712 >>> print(y.shape) 

713 (4, 26, 26, 26, 2) 

714 

715 >>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames, 

716 >>> # with 7 frames per video. 

717 >>> input_shape = (4, 7, 28, 28, 28, 1) 

718 >>> x = tf.random.normal(input_shape) 

719 >>> y = tf.keras.layers.Conv3D( 

720 ... 2, 3, activation='relu', input_shape=input_shape[2:])(x) 

721 >>> print(y.shape) 

722 (4, 7, 26, 26, 26, 2) 

723 

724 Args: 

725 filters: Integer, the dimensionality of the output space (i.e. the number of 

726 output filters in the convolution). 

727 kernel_size: An integer or tuple/list of 3 integers, specifying the depth, 

728 height and width of the 3D convolution window. Can be a single integer to 

729 specify the same value for all spatial dimensions. 

730 strides: An integer or tuple/list of 3 integers, specifying the strides of 

731 the convolution along each spatial dimension. Can be a single integer to 

732 specify the same value for all spatial dimensions. Specifying any stride 

733 value != 1 is incompatible with specifying any `dilation_rate` value != 1. 

734 padding: one of `"valid"` or `"same"` (case-insensitive). 

735 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

736 to the left/right or up/down of the input such that output has the same 

737 height/width dimension as the input. 

738 data_format: A string, one of `channels_last` (default) or `channels_first`. 

739 The ordering of the dimensions in the inputs. `channels_last` corresponds 

740 to inputs with shape `batch_shape + (spatial_dim1, spatial_dim2, 

741 spatial_dim3, channels)` while `channels_first` corresponds to inputs with 

742 shape `batch_shape + (channels, spatial_dim1, spatial_dim2, 

743 spatial_dim3)`. It defaults to the `image_data_format` value found in your 

744 Keras config file at `~/.keras/keras.json`. If you never set it, then it 

745 will be "channels_last". 

746 dilation_rate: an integer or tuple/list of 3 integers, specifying the 

747 dilation rate to use for dilated convolution. Can be a single integer to 

748 specify the same value for all spatial dimensions. Currently, specifying 

749 any `dilation_rate` value != 1 is incompatible with specifying any stride 

750 value != 1. 

751 groups: A positive integer specifying the number of groups in which the 

752 input is split along the channel axis. Each group is convolved separately 

753 with `filters / groups` filters. The output is the concatenation of all 

754 the `groups` results along the channel axis. Input channels and `filters` 

755 must both be divisible by `groups`. 

756 activation: Activation function to use. If you don't specify anything, no 

757 activation is applied (see `keras.activations`). 

758 use_bias: Boolean, whether the layer uses a bias vector. 

759 kernel_initializer: Initializer for the `kernel` weights matrix (see 

760 `keras.initializers`). Defaults to 'glorot_uniform'. 

761 bias_initializer: Initializer for the bias vector (see 

762 `keras.initializers`). Defaults to 'zeros'. 

763 kernel_regularizer: Regularizer function applied to the `kernel` weights 

764 matrix (see `keras.regularizers`). 

765 bias_regularizer: Regularizer function applied to the bias vector (see 

766 `keras.regularizers`). 

767 activity_regularizer: Regularizer function applied to the output of the 

768 layer (its "activation") (see `keras.regularizers`). 

769 kernel_constraint: Constraint function applied to the kernel matrix (see 

770 `keras.constraints`). 

771 bias_constraint: Constraint function applied to the bias vector (see 

772 `keras.constraints`). 

773 Input shape: 

774 5+D tensor with shape: `batch_shape + (channels, conv_dim1, conv_dim2, 

775 conv_dim3)` if data_format='channels_first' 

776 or 5+D tensor with shape: `batch_shape + (conv_dim1, conv_dim2, conv_dim3, 

777 channels)` if data_format='channels_last'. 

778 Output shape: 

779 5+D tensor with shape: `batch_shape + (filters, new_conv_dim1, 

780 new_conv_dim2, new_conv_dim3)` if data_format='channels_first' 

781 or 5+D tensor with shape: `batch_shape + (new_conv_dim1, new_conv_dim2, 

782 new_conv_dim3, filters)` if data_format='channels_last'. `new_conv_dim1`, 

783 `new_conv_dim2` and `new_conv_dim3` values might have changed due to 

784 padding. 

785 

786 Returns: 

787 A tensor of rank 5+ representing 

788 `activation(conv3d(inputs, kernel) + bias)`. 

789 

790 Raises: 

791 ValueError: if `padding` is "causal". 

792 ValueError: when both `strides > 1` and `dilation_rate > 1`. 

793 """ 

794 

795 def __init__(self, 

796 filters, 

797 kernel_size, 

798 strides=(1, 1, 1), 

799 padding='valid', 

800 data_format=None, 

801 dilation_rate=(1, 1, 1), 

802 groups=1, 

803 activation=None, 

804 use_bias=True, 

805 kernel_initializer='glorot_uniform', 

806 bias_initializer='zeros', 

807 kernel_regularizer=None, 

808 bias_regularizer=None, 

809 activity_regularizer=None, 

810 kernel_constraint=None, 

811 bias_constraint=None, 

812 **kwargs): 

813 super(Conv3D, self).__init__( 

814 rank=3, 

815 filters=filters, 

816 kernel_size=kernel_size, 

817 strides=strides, 

818 padding=padding, 

819 data_format=data_format, 

820 dilation_rate=dilation_rate, 

821 groups=groups, 

822 activation=activations.get(activation), 

823 use_bias=use_bias, 

824 kernel_initializer=initializers.get(kernel_initializer), 

825 bias_initializer=initializers.get(bias_initializer), 

826 kernel_regularizer=regularizers.get(kernel_regularizer), 

827 bias_regularizer=regularizers.get(bias_regularizer), 

828 activity_regularizer=regularizers.get(activity_regularizer), 

829 kernel_constraint=constraints.get(kernel_constraint), 

830 bias_constraint=constraints.get(bias_constraint), 

831 **kwargs) 

832 

833 

834@keras_export('keras.layers.Conv1DTranspose', 

835 'keras.layers.Convolution1DTranspose') 

836class Conv1DTranspose(Conv1D): 

837 """Transposed convolution layer (sometimes called Deconvolution). 

838 

839 The need for transposed convolutions generally arises 

840 from the desire to use a transformation going in the opposite direction 

841 of a normal convolution, i.e., from something that has the shape of the 

842 output of some convolution to something that has the shape of its input 

843 while maintaining a connectivity pattern that is compatible with 

844 said convolution. 

845 

846 When using this layer as the first layer in a model, 

847 provide the keyword argument `input_shape` 

848 (tuple of integers or `None`, does not include the sample axis), 

849 e.g. `input_shape=(128, 3)` for data with 128 time steps and 3 channels. 

850 

851 Args: 

852 filters: Integer, the dimensionality of the output space 

853 (i.e. the number of output filters in the convolution). 

854 kernel_size: An integer length of the 1D convolution window. 

855 strides: An integer specifying the stride of the convolution along the 

856 time dimension. Specifying a stride value != 1 is incompatible with 

857 specifying a `dilation_rate` value != 1. Defaults to 1. 

858 padding: one of `"valid"` or `"same"` (case-insensitive). 

859 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

860 to the left/right or up/down of the input such that output has the same 

861 height/width dimension as the input. 

862 output_padding: An integer specifying the amount of padding along 

863 the time dimension of the output tensor. 

864 The amount of output padding must be lower than the stride. 

865 If set to `None` (default), the output shape is inferred. 

866 data_format: A string, one of `channels_last` (default) or `channels_first`. 

867 The ordering of the dimensions in the inputs. 

868 `channels_last` corresponds to inputs with shape 

869 `(batch_size, length, channels)` while `channels_first` corresponds to 

870 inputs with shape `(batch_size, channels, length)`. 

871 dilation_rate: an integer, specifying 

872 the dilation rate to use for dilated convolution. 

873 Currently, specifying a `dilation_rate` value != 1 is 

874 incompatible with specifying a stride value != 1. 

875 Also dilation rate larger than 1 is not currently supported. 

876 activation: Activation function to use. 

877 If you don't specify anything, no activation is applied ( 

878 see `keras.activations`). 

879 use_bias: Boolean, whether the layer uses a bias vector. 

880 kernel_initializer: Initializer for the `kernel` weights matrix ( 

881 see `keras.initializers`). Defaults to 'glorot_uniform'. 

882 bias_initializer: Initializer for the bias vector ( 

883 see `keras.initializers`). Defaults to 'zeros'. 

884 kernel_regularizer: Regularizer function applied to 

885 the `kernel` weights matrix (see `keras.regularizers`). 

886 bias_regularizer: Regularizer function applied to the bias vector ( 

887 see `keras.regularizers`). 

888 activity_regularizer: Regularizer function applied to 

889 the output of the layer (its "activation") (see `keras.regularizers`). 

890 kernel_constraint: Constraint function applied to the kernel matrix ( 

891 see `keras.constraints`). 

892 bias_constraint: Constraint function applied to the bias vector ( 

893 see `keras.constraints`). 

894 

895 Input shape: 

896 3D tensor with shape: 

897 `(batch_size, steps, channels)` 

898 

899 Output shape: 

900 3D tensor with shape: 

901 `(batch_size, new_steps, filters)` 

902 If `output_padding` is specified: 

903 ``` 

904 new_timesteps = ((timesteps - 1) * strides + kernel_size - 

905 2 * padding + output_padding) 

906 ``` 

907 

908 Returns: 

909 A tensor of rank 3 representing 

910 `activation(conv1dtranspose(inputs, kernel) + bias)`. 

911 

912 Raises: 

913 ValueError: if `padding` is "causal". 

914 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

915 

916 References: 

917 - [A guide to convolution arithmetic for deep learning]( 

918 https://arxiv.org/abs/1603.07285v1) 

919 - [Deconvolutional Networks]( 

920 https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf) 

921 """ 

922 

923 def __init__(self, 

924 filters, 

925 kernel_size, 

926 strides=1, 

927 padding='valid', 

928 output_padding=None, 

929 data_format=None, 

930 dilation_rate=1, 

931 activation=None, 

932 use_bias=True, 

933 kernel_initializer='glorot_uniform', 

934 bias_initializer='zeros', 

935 kernel_regularizer=None, 

936 bias_regularizer=None, 

937 activity_regularizer=None, 

938 kernel_constraint=None, 

939 bias_constraint=None, 

940 **kwargs): 

941 super(Conv1DTranspose, self).__init__( 

942 filters=filters, 

943 kernel_size=kernel_size, 

944 strides=strides, 

945 padding=padding, 

946 data_format=data_format, 

947 dilation_rate=dilation_rate, 

948 activation=activations.get(activation), 

949 use_bias=use_bias, 

950 kernel_initializer=initializers.get(kernel_initializer), 

951 bias_initializer=initializers.get(bias_initializer), 

952 kernel_regularizer=regularizers.get(kernel_regularizer), 

953 bias_regularizer=regularizers.get(bias_regularizer), 

954 activity_regularizer=regularizers.get(activity_regularizer), 

955 kernel_constraint=constraints.get(kernel_constraint), 

956 bias_constraint=constraints.get(bias_constraint), 

957 **kwargs) 

958 

959 self.output_padding = output_padding 

960 if self.output_padding is not None: 

961 self.output_padding = conv_utils.normalize_tuple( 

962 self.output_padding, 1, 'output_padding') 

963 for stride, out_pad in zip(self.strides, self.output_padding): 

964 if out_pad >= stride: 

965 raise ValueError('Stride ' + str(self.strides) + ' must be ' 

966 'greater than output padding ' + 

967 str(self.output_padding)) 

968 

969 def build(self, input_shape): 

970 input_shape = tensor_shape.TensorShape(input_shape) 

971 if len(input_shape) != 3: 

972 raise ValueError('Inputs should have rank 3. Received input shape: ' + 

973 str(input_shape)) 

974 channel_axis = self._get_channel_axis() 

975 if input_shape.dims[channel_axis].value is None: 

976 raise ValueError('The channel dimension of the inputs ' 

977 'should be defined. Found `None`.') 

978 input_dim = int(input_shape[channel_axis]) 

979 self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim}) 

980 kernel_shape = self.kernel_size + (self.filters, input_dim) 

981 

982 self.kernel = self.add_weight( 

983 name='kernel', 

984 shape=kernel_shape, 

985 initializer=self.kernel_initializer, 

986 regularizer=self.kernel_regularizer, 

987 constraint=self.kernel_constraint, 

988 trainable=True, 

989 dtype=self.dtype) 

990 if self.use_bias: 

991 self.bias = self.add_weight( 

992 name='bias', 

993 shape=(self.filters,), 

994 initializer=self.bias_initializer, 

995 regularizer=self.bias_regularizer, 

996 constraint=self.bias_constraint, 

997 trainable=True, 

998 dtype=self.dtype) 

999 else: 

1000 self.bias = None 

1001 self.built = True 

1002 

1003 def call(self, inputs): 

1004 inputs_shape = array_ops.shape(inputs) 

1005 batch_size = inputs_shape[0] 

1006 if self.data_format == 'channels_first': 

1007 t_axis = 2 

1008 else: 

1009 t_axis = 1 

1010 

1011 length = inputs_shape[t_axis] 

1012 if self.output_padding is None: 

1013 output_padding = None 

1014 else: 

1015 output_padding = self.output_padding[0] 

1016 

1017 # Infer the dynamic output shape: 

1018 out_length = conv_utils.deconv_output_length( 

1019 length, self.kernel_size[0], padding=self.padding, 

1020 output_padding=output_padding, stride=self.strides[0], 

1021 dilation=self.dilation_rate[0]) 

1022 if self.data_format == 'channels_first': 

1023 output_shape = (batch_size, self.filters, out_length) 

1024 else: 

1025 output_shape = (batch_size, out_length, self.filters) 

1026 data_format = conv_utils.convert_data_format(self.data_format, ndim=3) 

1027 

1028 output_shape_tensor = array_ops_stack.stack(output_shape) 

1029 outputs = nn_ops.conv1d_transpose( 

1030 inputs, 

1031 self.kernel, 

1032 output_shape_tensor, 

1033 strides=self.strides, 

1034 padding=self.padding.upper(), 

1035 data_format=data_format, 

1036 dilations=self.dilation_rate) 

1037 

1038 if not context.executing_eagerly(): 

1039 # Infer the static output shape: 

1040 out_shape = self.compute_output_shape(inputs.shape) 

1041 outputs.set_shape(out_shape) 

1042 

1043 if self.use_bias: 

1044 outputs = nn.bias_add( 

1045 outputs, 

1046 self.bias, 

1047 data_format=data_format) 

1048 

1049 if self.activation is not None: 

1050 return self.activation(outputs) 

1051 return outputs 

1052 

1053 def compute_output_shape(self, input_shape): 

1054 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

1055 output_shape = list(input_shape) 

1056 if self.data_format == 'channels_first': 

1057 c_axis, t_axis = 1, 2 

1058 else: 

1059 c_axis, t_axis = 2, 1 

1060 

1061 if self.output_padding is None: 

1062 output_padding = None 

1063 else: 

1064 output_padding = self.output_padding[0] 

1065 output_shape[c_axis] = self.filters 

1066 output_shape[t_axis] = conv_utils.deconv_output_length( 

1067 output_shape[t_axis], 

1068 self.kernel_size[0], 

1069 padding=self.padding, 

1070 output_padding=output_padding, 

1071 stride=self.strides[0], 

1072 dilation=self.dilation_rate[0]) 

1073 return tensor_shape.TensorShape(output_shape) 

1074 

1075 def get_config(self): 

1076 config = super(Conv1DTranspose, self).get_config() 

1077 config['output_padding'] = self.output_padding 

1078 return config 

1079 

1080 

1081@keras_export('keras.layers.Conv2DTranspose', 

1082 'keras.layers.Convolution2DTranspose') 

1083class Conv2DTranspose(Conv2D): 

1084 """Transposed convolution layer (sometimes called Deconvolution). 

1085 

1086 The need for transposed convolutions generally arises 

1087 from the desire to use a transformation going in the opposite direction 

1088 of a normal convolution, i.e., from something that has the shape of the 

1089 output of some convolution to something that has the shape of its input 

1090 while maintaining a connectivity pattern that is compatible with 

1091 said convolution. 

1092 

1093 When using this layer as the first layer in a model, 

1094 provide the keyword argument `input_shape` 

1095 (tuple of integers or `None`, does not include the sample axis), 

1096 e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures 

1097 in `data_format="channels_last"`. 

1098 

1099 Args: 

1100 filters: Integer, the dimensionality of the output space 

1101 (i.e. the number of output filters in the convolution). 

1102 kernel_size: An integer or tuple/list of 2 integers, specifying the 

1103 height and width of the 2D convolution window. 

1104 Can be a single integer to specify the same value for 

1105 all spatial dimensions. 

1106 strides: An integer or tuple/list of 2 integers, 

1107 specifying the strides of the convolution along the height and width. 

1108 Can be a single integer to specify the same value for 

1109 all spatial dimensions. 

1110 Specifying any stride value != 1 is incompatible with specifying 

1111 any `dilation_rate` value != 1. 

1112 padding: one of `"valid"` or `"same"` (case-insensitive). 

1113 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

1114 to the left/right or up/down of the input such that output has the same 

1115 height/width dimension as the input. 

1116 output_padding: An integer or tuple/list of 2 integers, 

1117 specifying the amount of padding along the height and width 

1118 of the output tensor. 

1119 Can be a single integer to specify the same value for all 

1120 spatial dimensions. 

1121 The amount of output padding along a given dimension must be 

1122 lower than the stride along that same dimension. 

1123 If set to `None` (default), the output shape is inferred. 

1124 data_format: A string, 

1125 one of `channels_last` (default) or `channels_first`. 

1126 The ordering of the dimensions in the inputs. 

1127 `channels_last` corresponds to inputs with shape 

1128 `(batch_size, height, width, channels)` while `channels_first` 

1129 corresponds to inputs with shape 

1130 `(batch_size, channels, height, width)`. 

1131 It defaults to the `image_data_format` value found in your 

1132 Keras config file at `~/.keras/keras.json`. 

1133 If you never set it, then it will be "channels_last". 

1134 dilation_rate: an integer or tuple/list of 2 integers, specifying 

1135 the dilation rate to use for dilated convolution. 

1136 Can be a single integer to specify the same value for 

1137 all spatial dimensions. 

1138 Currently, specifying any `dilation_rate` value != 1 is 

1139 incompatible with specifying any stride value != 1. 

1140 activation: Activation function to use. 

1141 If you don't specify anything, no activation is applied ( 

1142 see `keras.activations`). 

1143 use_bias: Boolean, whether the layer uses a bias vector. 

1144 kernel_initializer: Initializer for the `kernel` weights matrix ( 

1145 see `keras.initializers`). Defaults to 'glorot_uniform'. 

1146 bias_initializer: Initializer for the bias vector ( 

1147 see `keras.initializers`). Defaults to 'zeros'. 

1148 kernel_regularizer: Regularizer function applied to 

1149 the `kernel` weights matrix (see `keras.regularizers`). 

1150 bias_regularizer: Regularizer function applied to the bias vector ( 

1151 see `keras.regularizers`). 

1152 activity_regularizer: Regularizer function applied to 

1153 the output of the layer (its "activation") (see `keras.regularizers`). 

1154 kernel_constraint: Constraint function applied to the kernel matrix ( 

1155 see `keras.constraints`). 

1156 bias_constraint: Constraint function applied to the bias vector ( 

1157 see `keras.constraints`). 

1158 

1159 Input shape: 

1160 4D tensor with shape: 

1161 `(batch_size, channels, rows, cols)` if data_format='channels_first' 

1162 or 4D tensor with shape: 

1163 `(batch_size, rows, cols, channels)` if data_format='channels_last'. 

1164 

1165 Output shape: 

1166 4D tensor with shape: 

1167 `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first' 

1168 or 4D tensor with shape: 

1169 `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'. 

1170 `rows` and `cols` values might have changed due to padding. 

1171 If `output_padding` is specified: 

1172 ``` 

1173 new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + 

1174 output_padding[0]) 

1175 new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + 

1176 output_padding[1]) 

1177 ``` 

1178 

1179 Returns: 

1180 A tensor of rank 4 representing 

1181 `activation(conv2dtranspose(inputs, kernel) + bias)`. 

1182 

1183 Raises: 

1184 ValueError: if `padding` is "causal". 

1185 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

1186 

1187 References: 

1188 - [A guide to convolution arithmetic for deep 

1189 learning](https://arxiv.org/abs/1603.07285v1) 

1190 - [Deconvolutional 

1191 Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf) 

1192 """ 

1193 

1194 def __init__(self, 

1195 filters, 

1196 kernel_size, 

1197 strides=(1, 1), 

1198 padding='valid', 

1199 output_padding=None, 

1200 data_format=None, 

1201 dilation_rate=(1, 1), 

1202 activation=None, 

1203 use_bias=True, 

1204 kernel_initializer='glorot_uniform', 

1205 bias_initializer='zeros', 

1206 kernel_regularizer=None, 

1207 bias_regularizer=None, 

1208 activity_regularizer=None, 

1209 kernel_constraint=None, 

1210 bias_constraint=None, 

1211 **kwargs): 

1212 super(Conv2DTranspose, self).__init__( 

1213 filters=filters, 

1214 kernel_size=kernel_size, 

1215 strides=strides, 

1216 padding=padding, 

1217 data_format=data_format, 

1218 dilation_rate=dilation_rate, 

1219 activation=activations.get(activation), 

1220 use_bias=use_bias, 

1221 kernel_initializer=initializers.get(kernel_initializer), 

1222 bias_initializer=initializers.get(bias_initializer), 

1223 kernel_regularizer=regularizers.get(kernel_regularizer), 

1224 bias_regularizer=regularizers.get(bias_regularizer), 

1225 activity_regularizer=regularizers.get(activity_regularizer), 

1226 kernel_constraint=constraints.get(kernel_constraint), 

1227 bias_constraint=constraints.get(bias_constraint), 

1228 **kwargs) 

1229 

1230 self.output_padding = output_padding 

1231 if self.output_padding is not None: 

1232 self.output_padding = conv_utils.normalize_tuple( 

1233 self.output_padding, 2, 'output_padding') 

1234 for stride, out_pad in zip(self.strides, self.output_padding): 

1235 if out_pad >= stride: 

1236 raise ValueError('Stride ' + str(self.strides) + ' must be ' 

1237 'greater than output padding ' + 

1238 str(self.output_padding)) 

1239 

1240 def build(self, input_shape): 

1241 input_shape = tensor_shape.TensorShape(input_shape) 

1242 if len(input_shape) != 4: 

1243 raise ValueError('Inputs should have rank 4. Received input ' 

1244 'shape: ' + str(input_shape)) 

1245 channel_axis = self._get_channel_axis() 

1246 if input_shape.dims[channel_axis].value is None: 

1247 raise ValueError('The channel dimension of the inputs ' 

1248 'should be defined. Found `None`.') 

1249 input_dim = int(input_shape[channel_axis]) 

1250 self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim}) 

1251 kernel_shape = self.kernel_size + (self.filters, input_dim) 

1252 

1253 self.kernel = self.add_weight( 

1254 name='kernel', 

1255 shape=kernel_shape, 

1256 initializer=self.kernel_initializer, 

1257 regularizer=self.kernel_regularizer, 

1258 constraint=self.kernel_constraint, 

1259 trainable=True, 

1260 dtype=self.dtype) 

1261 if self.use_bias: 

1262 self.bias = self.add_weight( 

1263 name='bias', 

1264 shape=(self.filters,), 

1265 initializer=self.bias_initializer, 

1266 regularizer=self.bias_regularizer, 

1267 constraint=self.bias_constraint, 

1268 trainable=True, 

1269 dtype=self.dtype) 

1270 else: 

1271 self.bias = None 

1272 self.built = True 

1273 

1274 def call(self, inputs): 

1275 inputs_shape = array_ops.shape(inputs) 

1276 batch_size = inputs_shape[0] 

1277 if self.data_format == 'channels_first': 

1278 h_axis, w_axis = 2, 3 

1279 else: 

1280 h_axis, w_axis = 1, 2 

1281 

1282 # Use the constant height and weight when possible. 

1283 # TODO(scottzhu): Extract this into a utility function that can be applied 

1284 # to all convolutional layers, which currently lost the static shape 

1285 # information due to tf.shape(). 

1286 height, width = None, None 

1287 if inputs.shape.rank is not None: 

1288 dims = inputs.shape.as_list() 

1289 height = dims[h_axis] 

1290 width = dims[w_axis] 

1291 height = height if height is not None else inputs_shape[h_axis] 

1292 width = width if width is not None else inputs_shape[w_axis] 

1293 

1294 kernel_h, kernel_w = self.kernel_size 

1295 stride_h, stride_w = self.strides 

1296 

1297 if self.output_padding is None: 

1298 out_pad_h = out_pad_w = None 

1299 else: 

1300 out_pad_h, out_pad_w = self.output_padding 

1301 

1302 # Infer the dynamic output shape: 

1303 out_height = conv_utils.deconv_output_length(height, 

1304 kernel_h, 

1305 padding=self.padding, 

1306 output_padding=out_pad_h, 

1307 stride=stride_h, 

1308 dilation=self.dilation_rate[0]) 

1309 out_width = conv_utils.deconv_output_length(width, 

1310 kernel_w, 

1311 padding=self.padding, 

1312 output_padding=out_pad_w, 

1313 stride=stride_w, 

1314 dilation=self.dilation_rate[1]) 

1315 if self.data_format == 'channels_first': 

1316 output_shape = (batch_size, self.filters, out_height, out_width) 

1317 else: 

1318 output_shape = (batch_size, out_height, out_width, self.filters) 

1319 

1320 output_shape_tensor = array_ops_stack.stack(output_shape) 

1321 outputs = backend.conv2d_transpose( 

1322 inputs, 

1323 self.kernel, 

1324 output_shape_tensor, 

1325 strides=self.strides, 

1326 padding=self.padding, 

1327 data_format=self.data_format, 

1328 dilation_rate=self.dilation_rate) 

1329 

1330 if not context.executing_eagerly(): 

1331 # Infer the static output shape: 

1332 out_shape = self.compute_output_shape(inputs.shape) 

1333 outputs.set_shape(out_shape) 

1334 

1335 if self.use_bias: 

1336 outputs = nn.bias_add( 

1337 outputs, 

1338 self.bias, 

1339 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

1340 

1341 if self.activation is not None: 

1342 return self.activation(outputs) 

1343 return outputs 

1344 

1345 def compute_output_shape(self, input_shape): 

1346 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

1347 output_shape = list(input_shape) 

1348 if self.data_format == 'channels_first': 

1349 c_axis, h_axis, w_axis = 1, 2, 3 

1350 else: 

1351 c_axis, h_axis, w_axis = 3, 1, 2 

1352 

1353 kernel_h, kernel_w = self.kernel_size 

1354 stride_h, stride_w = self.strides 

1355 

1356 if self.output_padding is None: 

1357 out_pad_h = out_pad_w = None 

1358 else: 

1359 out_pad_h, out_pad_w = self.output_padding 

1360 

1361 output_shape[c_axis] = self.filters 

1362 output_shape[h_axis] = conv_utils.deconv_output_length( 

1363 output_shape[h_axis], 

1364 kernel_h, 

1365 padding=self.padding, 

1366 output_padding=out_pad_h, 

1367 stride=stride_h, 

1368 dilation=self.dilation_rate[0]) 

1369 output_shape[w_axis] = conv_utils.deconv_output_length( 

1370 output_shape[w_axis], 

1371 kernel_w, 

1372 padding=self.padding, 

1373 output_padding=out_pad_w, 

1374 stride=stride_w, 

1375 dilation=self.dilation_rate[1]) 

1376 return tensor_shape.TensorShape(output_shape) 

1377 

1378 def get_config(self): 

1379 config = super(Conv2DTranspose, self).get_config() 

1380 config['output_padding'] = self.output_padding 

1381 return config 

1382 

1383 

1384@keras_export('keras.layers.Conv3DTranspose', 

1385 'keras.layers.Convolution3DTranspose') 

1386class Conv3DTranspose(Conv3D): 

1387 """Transposed convolution layer (sometimes called Deconvolution). 

1388 

1389 The need for transposed convolutions generally arises 

1390 from the desire to use a transformation going in the opposite direction 

1391 of a normal convolution, i.e., from something that has the shape of the 

1392 output of some convolution to something that has the shape of its input 

1393 while maintaining a connectivity pattern that is compatible with 

1394 said convolution. 

1395 

1396 When using this layer as the first layer in a model, 

1397 provide the keyword argument `input_shape` 

1398 (tuple of integers or `None`, does not include the sample axis), 

1399 e.g. `input_shape=(128, 128, 128, 3)` for a 128x128x128 volume with 3 channels 

1400 if `data_format="channels_last"`. 

1401 

1402 Args: 

1403 filters: Integer, the dimensionality of the output space 

1404 (i.e. the number of output filters in the convolution). 

1405 kernel_size: An integer or tuple/list of 3 integers, specifying the 

1406 depth, height and width of the 3D convolution window. 

1407 Can be a single integer to specify the same value for 

1408 all spatial dimensions. 

1409 strides: An integer or tuple/list of 3 integers, 

1410 specifying the strides of the convolution along the depth, height 

1411 and width. 

1412 Can be a single integer to specify the same value for 

1413 all spatial dimensions. 

1414 Specifying any stride value != 1 is incompatible with specifying 

1415 any `dilation_rate` value != 1. 

1416 padding: one of `"valid"` or `"same"` (case-insensitive). 

1417 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

1418 to the left/right or up/down of the input such that output has the same 

1419 height/width dimension as the input. 

1420 output_padding: An integer or tuple/list of 3 integers, 

1421 specifying the amount of padding along the depth, height, and 

1422 width. 

1423 Can be a single integer to specify the same value for all 

1424 spatial dimensions. 

1425 The amount of output padding along a given dimension must be 

1426 lower than the stride along that same dimension. 

1427 If set to `None` (default), the output shape is inferred. 

1428 data_format: A string, 

1429 one of `channels_last` (default) or `channels_first`. 

1430 The ordering of the dimensions in the inputs. 

1431 `channels_last` corresponds to inputs with shape 

1432 `(batch_size, depth, height, width, channels)` while `channels_first` 

1433 corresponds to inputs with shape 

1434 `(batch_size, channels, depth, height, width)`. 

1435 It defaults to the `image_data_format` value found in your 

1436 Keras config file at `~/.keras/keras.json`. 

1437 If you never set it, then it will be "channels_last". 

1438 dilation_rate: an integer or tuple/list of 3 integers, specifying 

1439 the dilation rate to use for dilated convolution. 

1440 Can be a single integer to specify the same value for 

1441 all spatial dimensions. 

1442 Currently, specifying any `dilation_rate` value != 1 is 

1443 incompatible with specifying any stride value != 1. 

1444 activation: Activation function to use. 

1445 If you don't specify anything, no activation is applied ( 

1446 see `keras.activations`). 

1447 use_bias: Boolean, whether the layer uses a bias vector. 

1448 kernel_initializer: Initializer for the `kernel` weights matrix ( 

1449 see `keras.initializers`). Defaults to 'glorot_uniform'. 

1450 bias_initializer: Initializer for the bias vector ( 

1451 see `keras.initializers`). Defaults to 'zeros'. 

1452 kernel_regularizer: Regularizer function applied to 

1453 the `kernel` weights matrix ( 

1454 see `keras.regularizers`). 

1455 bias_regularizer: Regularizer function applied to the bias vector ( 

1456 see `keras.regularizers`). 

1457 activity_regularizer: Regularizer function applied to 

1458 the output of the layer (its "activation") ( 

1459 see `keras.regularizers`). 

1460 kernel_constraint: Constraint function applied to the kernel matrix ( 

1461 see `keras.constraints`). 

1462 bias_constraint: Constraint function applied to the bias vector ( 

1463 see `keras.constraints`). 

1464 

1465 Input shape: 

1466 5D tensor with shape: 

1467 `(batch_size, channels, depth, rows, cols)` if data_format='channels_first' 

1468 or 5D tensor with shape: 

1469 `(batch_size, depth, rows, cols, channels)` if data_format='channels_last'. 

1470 

1471 Output shape: 

1472 5D tensor with shape: 

1473 `(batch_size, filters, new_depth, new_rows, new_cols)` if 

1474 data_format='channels_first' 

1475 or 5D tensor with shape: 

1476 `(batch_size, new_depth, new_rows, new_cols, filters)` if 

1477 data_format='channels_last'. 

1478 `depth` and `rows` and `cols` values might have changed due to padding. 

1479 If `output_padding` is specified:: 

1480 ``` 

1481 new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + 

1482 output_padding[0]) 

1483 new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + 

1484 output_padding[1]) 

1485 new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] + 

1486 output_padding[2]) 

1487 ``` 

1488 

1489 Returns: 

1490 A tensor of rank 5 representing 

1491 `activation(conv3dtranspose(inputs, kernel) + bias)`. 

1492 

1493 Raises: 

1494 ValueError: if `padding` is "causal". 

1495 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

1496 

1497 References: 

1498 - [A guide to convolution arithmetic for deep 

1499 learning](https://arxiv.org/abs/1603.07285v1) 

1500 - [Deconvolutional 

1501 Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf) 

1502 """ 

1503 

1504 def __init__(self, 

1505 filters, 

1506 kernel_size, 

1507 strides=(1, 1, 1), 

1508 padding='valid', 

1509 output_padding=None, 

1510 data_format=None, 

1511 dilation_rate=(1, 1, 1), 

1512 activation=None, 

1513 use_bias=True, 

1514 kernel_initializer='glorot_uniform', 

1515 bias_initializer='zeros', 

1516 kernel_regularizer=None, 

1517 bias_regularizer=None, 

1518 activity_regularizer=None, 

1519 kernel_constraint=None, 

1520 bias_constraint=None, 

1521 **kwargs): 

1522 super(Conv3DTranspose, self).__init__( 

1523 filters=filters, 

1524 kernel_size=kernel_size, 

1525 strides=strides, 

1526 padding=padding, 

1527 data_format=data_format, 

1528 dilation_rate=dilation_rate, 

1529 activation=activations.get(activation), 

1530 use_bias=use_bias, 

1531 kernel_initializer=initializers.get(kernel_initializer), 

1532 bias_initializer=initializers.get(bias_initializer), 

1533 kernel_regularizer=regularizers.get(kernel_regularizer), 

1534 bias_regularizer=regularizers.get(bias_regularizer), 

1535 activity_regularizer=regularizers.get(activity_regularizer), 

1536 kernel_constraint=constraints.get(kernel_constraint), 

1537 bias_constraint=constraints.get(bias_constraint), 

1538 **kwargs) 

1539 

1540 self.output_padding = output_padding 

1541 if self.output_padding is not None: 

1542 self.output_padding = conv_utils.normalize_tuple( 

1543 self.output_padding, 3, 'output_padding') 

1544 for stride, out_pad in zip(self.strides, self.output_padding): 

1545 if out_pad >= stride: 

1546 raise ValueError('Stride ' + str(self.strides) + ' must be ' 

1547 'greater than output padding ' + 

1548 str(self.output_padding)) 

1549 

1550 def build(self, input_shape): 

1551 input_shape = tensor_shape.TensorShape(input_shape) 

1552 if len(input_shape) != 5: 

1553 raise ValueError('Inputs should have rank 5, received input shape:', 

1554 str(input_shape)) 

1555 channel_axis = self._get_channel_axis() 

1556 if input_shape.dims[channel_axis].value is None: 

1557 raise ValueError('The channel dimension of the inputs ' 

1558 'should be defined, found None: ' + str(input_shape)) 

1559 input_dim = int(input_shape[channel_axis]) 

1560 kernel_shape = self.kernel_size + (self.filters, input_dim) 

1561 self.input_spec = InputSpec(ndim=5, axes={channel_axis: input_dim}) 

1562 

1563 self.kernel = self.add_weight( 

1564 'kernel', 

1565 shape=kernel_shape, 

1566 initializer=self.kernel_initializer, 

1567 regularizer=self.kernel_regularizer, 

1568 constraint=self.kernel_constraint, 

1569 trainable=True, 

1570 dtype=self.dtype) 

1571 if self.use_bias: 

1572 self.bias = self.add_weight( 

1573 'bias', 

1574 shape=(self.filters,), 

1575 initializer=self.bias_initializer, 

1576 regularizer=self.bias_regularizer, 

1577 constraint=self.bias_constraint, 

1578 trainable=True, 

1579 dtype=self.dtype) 

1580 else: 

1581 self.bias = None 

1582 self.built = True 

1583 

1584 def call(self, inputs): 

1585 inputs_shape = array_ops.shape(inputs) 

1586 batch_size = inputs_shape[0] 

1587 if self.data_format == 'channels_first': 

1588 d_axis, h_axis, w_axis = 2, 3, 4 

1589 else: 

1590 d_axis, h_axis, w_axis = 1, 2, 3 

1591 

1592 depth = inputs_shape[d_axis] 

1593 height = inputs_shape[h_axis] 

1594 width = inputs_shape[w_axis] 

1595 

1596 kernel_d, kernel_h, kernel_w = self.kernel_size 

1597 stride_d, stride_h, stride_w = self.strides 

1598 

1599 if self.output_padding is None: 

1600 out_pad_d = out_pad_h = out_pad_w = None 

1601 else: 

1602 out_pad_d, out_pad_h, out_pad_w = self.output_padding 

1603 

1604 # Infer the dynamic output shape: 

1605 out_depth = conv_utils.deconv_output_length(depth, 

1606 kernel_d, 

1607 padding=self.padding, 

1608 output_padding=out_pad_d, 

1609 stride=stride_d) 

1610 out_height = conv_utils.deconv_output_length(height, 

1611 kernel_h, 

1612 padding=self.padding, 

1613 output_padding=out_pad_h, 

1614 stride=stride_h) 

1615 out_width = conv_utils.deconv_output_length(width, 

1616 kernel_w, 

1617 padding=self.padding, 

1618 output_padding=out_pad_w, 

1619 stride=stride_w) 

1620 if self.data_format == 'channels_first': 

1621 output_shape = (batch_size, self.filters, out_depth, out_height, 

1622 out_width) 

1623 strides = (1, 1, stride_d, stride_h, stride_w) 

1624 else: 

1625 output_shape = (batch_size, out_depth, out_height, out_width, 

1626 self.filters) 

1627 strides = (1, stride_d, stride_h, stride_w, 1) 

1628 

1629 output_shape_tensor = array_ops_stack.stack(output_shape) 

1630 outputs = nn.conv3d_transpose( 

1631 inputs, 

1632 self.kernel, 

1633 output_shape_tensor, 

1634 strides, 

1635 data_format=conv_utils.convert_data_format(self.data_format, ndim=5), 

1636 padding=self.padding.upper()) 

1637 

1638 if not context.executing_eagerly(): 

1639 # Infer the static output shape: 

1640 out_shape = self.compute_output_shape(inputs.shape) 

1641 outputs.set_shape(out_shape) 

1642 

1643 if self.use_bias: 

1644 outputs = nn.bias_add( 

1645 outputs, 

1646 self.bias, 

1647 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

1648 

1649 if self.activation is not None: 

1650 return self.activation(outputs) 

1651 return outputs 

1652 

1653 def compute_output_shape(self, input_shape): 

1654 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

1655 output_shape = list(input_shape) 

1656 if self.data_format == 'channels_first': 

1657 c_axis, d_axis, h_axis, w_axis = 1, 2, 3, 4 

1658 else: 

1659 c_axis, d_axis, h_axis, w_axis = 4, 1, 2, 3 

1660 

1661 kernel_d, kernel_h, kernel_w = self.kernel_size 

1662 stride_d, stride_h, stride_w = self.strides 

1663 

1664 if self.output_padding is None: 

1665 out_pad_d = out_pad_h = out_pad_w = None 

1666 else: 

1667 out_pad_d, out_pad_h, out_pad_w = self.output_padding 

1668 

1669 output_shape[c_axis] = self.filters 

1670 output_shape[d_axis] = conv_utils.deconv_output_length( 

1671 output_shape[d_axis], 

1672 kernel_d, 

1673 padding=self.padding, 

1674 output_padding=out_pad_d, 

1675 stride=stride_d) 

1676 output_shape[h_axis] = conv_utils.deconv_output_length( 

1677 output_shape[h_axis], 

1678 kernel_h, 

1679 padding=self.padding, 

1680 output_padding=out_pad_h, 

1681 stride=stride_h) 

1682 output_shape[w_axis] = conv_utils.deconv_output_length( 

1683 output_shape[w_axis], 

1684 kernel_w, 

1685 padding=self.padding, 

1686 output_padding=out_pad_w, 

1687 stride=stride_w) 

1688 return tensor_shape.TensorShape(output_shape) 

1689 

1690 def get_config(self): 

1691 config = super(Conv3DTranspose, self).get_config() 

1692 config.pop('dilation_rate') 

1693 config['output_padding'] = self.output_padding 

1694 return config 

1695 

1696 

1697class SeparableConv(Conv): 

1698 """Abstract base layer for separable nD convolution. 

1699 

1700 This layer performs a depthwise convolution that acts separately on 

1701 channels, followed by a pointwise convolution that mixes channels. 

1702 If `use_bias` is True and a bias initializer is provided, 

1703 it adds a bias vector to the output. 

1704 It then optionally applies an activation function to produce the final output. 

1705 

1706 Args: 

1707 rank: An integer, the rank of the convolution, e.g. "2" for 2D convolution. 

1708 filters: Integer, the dimensionality of the output space (i.e. the number 

1709 of filters in the convolution). 

1710 kernel_size: A tuple or list of integers specifying the spatial 

1711 dimensions of the filters. Can be a single integer to specify the same 

1712 value for all spatial dimensions. 

1713 strides: A tuple or list of integers specifying the strides 

1714 of the convolution. Can be a single integer to specify the same value for 

1715 all spatial dimensions. 

1716 Specifying any `stride` value != 1 is incompatible with specifying 

1717 any `dilation_rate` value != 1. 

1718 padding: One of `"valid"` or `"same"` (case-insensitive). 

1719 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

1720 to the left/right or up/down of the input such that output has the same 

1721 height/width dimension as the input. 

1722 data_format: A string, one of `channels_last` (default) or `channels_first`. 

1723 The ordering of the dimensions in the inputs. 

1724 `channels_last` corresponds to inputs with shape 

1725 `(batch_size, ..., channels)` while `channels_first` corresponds to 

1726 inputs with shape `(batch_size, channels, ...)`. 

1727 dilation_rate: An integer or tuple/list of 2 integers, specifying 

1728 the dilation rate to use for dilated convolution. 

1729 Can be a single integer to specify the same value for 

1730 all spatial dimensions. 

1731 Currently, specifying any `dilation_rate` value != 1 is 

1732 incompatible with specifying any stride value != 1. 

1733 depth_multiplier: The number of depthwise convolution output channels for 

1734 each input channel. The total number of depthwise convolution output 

1735 channels will be equal to `num_filters_in * depth_multiplier`. 

1736 activation: Activation function to use. 

1737 If you don't specify anything, no activation is applied ( 

1738 see `keras.activations`). 

1739 use_bias: Boolean, whether the layer uses a bias. 

1740 depthwise_initializer: An initializer for the depthwise convolution kernel ( 

1741 see `keras.initializers`). If None, then the default initializer ( 

1742 'glorot_uniform') will be used. 

1743 pointwise_initializer: An initializer for the pointwise convolution kernel ( 

1744 see `keras.initializers`). If None, then the default initializer  

1745 ('glorot_uniform') will be used. 

1746 bias_initializer: An initializer for the bias vector. If None, the default 

1747 initializer ('zeros') will be used (see `keras.initializers`). 

1748 depthwise_regularizer: Optional regularizer for the depthwise 

1749 convolution kernel. 

1750 pointwise_regularizer: Optional regularizer for the pointwise 

1751 convolution kernel. 

1752 bias_regularizer: Optional regularizer for the bias vector. 

1753 activity_regularizer: Optional regularizer function for the output. 

1754 depthwise_constraint: Optional projection function to be applied to the 

1755 depthwise kernel after being updated by an `Optimizer` (e.g. used for 

1756 norm constraints or value constraints for layer weights). The function 

1757 must take as input the unprojected variable and must return the 

1758 projected variable (which must have the same shape). Constraints are 

1759 not safe to use when doing asynchronous distributed training. 

1760 pointwise_constraint: Optional projection function to be applied to the 

1761 pointwise kernel after being updated by an `Optimizer`. 

1762 bias_constraint: Optional projection function to be applied to the 

1763 bias after being updated by an `Optimizer`. 

1764 trainable: Boolean, if `True` the weights of this layer will be marked as 

1765 trainable (and listed in `layer.trainable_weights`). 

1766 """ 

1767 

1768 def __init__(self, 

1769 rank, 

1770 filters, 

1771 kernel_size, 

1772 strides=1, 

1773 padding='valid', 

1774 data_format=None, 

1775 dilation_rate=1, 

1776 depth_multiplier=1, 

1777 activation=None, 

1778 use_bias=True, 

1779 depthwise_initializer='glorot_uniform', 

1780 pointwise_initializer='glorot_uniform', 

1781 bias_initializer='zeros', 

1782 depthwise_regularizer=None, 

1783 pointwise_regularizer=None, 

1784 bias_regularizer=None, 

1785 activity_regularizer=None, 

1786 depthwise_constraint=None, 

1787 pointwise_constraint=None, 

1788 bias_constraint=None, 

1789 trainable=True, 

1790 name=None, 

1791 **kwargs): 

1792 super(SeparableConv, self).__init__( 

1793 rank=rank, 

1794 filters=filters, 

1795 kernel_size=kernel_size, 

1796 strides=strides, 

1797 padding=padding, 

1798 data_format=data_format, 

1799 dilation_rate=dilation_rate, 

1800 activation=activations.get(activation), 

1801 use_bias=use_bias, 

1802 bias_initializer=initializers.get(bias_initializer), 

1803 bias_regularizer=regularizers.get(bias_regularizer), 

1804 activity_regularizer=regularizers.get(activity_regularizer), 

1805 bias_constraint=bias_constraint, 

1806 trainable=trainable, 

1807 name=name, 

1808 **kwargs) 

1809 self.depth_multiplier = depth_multiplier 

1810 self.depthwise_initializer = initializers.get(depthwise_initializer) 

1811 self.pointwise_initializer = initializers.get(pointwise_initializer) 

1812 self.depthwise_regularizer = regularizers.get(depthwise_regularizer) 

1813 self.pointwise_regularizer = regularizers.get(pointwise_regularizer) 

1814 self.depthwise_constraint = constraints.get(depthwise_constraint) 

1815 self.pointwise_constraint = constraints.get(pointwise_constraint) 

1816 

1817 def build(self, input_shape): 

1818 input_shape = tensor_shape.TensorShape(input_shape) 

1819 channel_axis = self._get_channel_axis() 

1820 if input_shape.dims[channel_axis].value is None: 

1821 raise ValueError('The channel dimension of the inputs ' 

1822 'should be defined. Found `None`.') 

1823 input_dim = int(input_shape[channel_axis]) 

1824 self.input_spec = InputSpec(ndim=self.rank + 2, 

1825 axes={channel_axis: input_dim}) 

1826 depthwise_kernel_shape = self.kernel_size + (input_dim, 

1827 self.depth_multiplier) 

1828 pointwise_kernel_shape = ( 

1829 1,) * self.rank + (self.depth_multiplier * input_dim, self.filters) 

1830 

1831 self.depthwise_kernel = self.add_weight( 

1832 name='depthwise_kernel', 

1833 shape=depthwise_kernel_shape, 

1834 initializer=self.depthwise_initializer, 

1835 regularizer=self.depthwise_regularizer, 

1836 constraint=self.depthwise_constraint, 

1837 trainable=True, 

1838 dtype=self.dtype) 

1839 self.pointwise_kernel = self.add_weight( 

1840 name='pointwise_kernel', 

1841 shape=pointwise_kernel_shape, 

1842 initializer=self.pointwise_initializer, 

1843 regularizer=self.pointwise_regularizer, 

1844 constraint=self.pointwise_constraint, 

1845 trainable=True, 

1846 dtype=self.dtype) 

1847 if self.use_bias: 

1848 self.bias = self.add_weight( 

1849 name='bias', 

1850 shape=(self.filters,), 

1851 initializer=self.bias_initializer, 

1852 regularizer=self.bias_regularizer, 

1853 constraint=self.bias_constraint, 

1854 trainable=True, 

1855 dtype=self.dtype) 

1856 else: 

1857 self.bias = None 

1858 self.built = True 

1859 

1860 def call(self, inputs): 

1861 raise NotImplementedError 

1862 

1863 def get_config(self): 

1864 config = { 

1865 'filters': 

1866 self.filters, 

1867 'kernel_size': 

1868 self.kernel_size, 

1869 'strides': 

1870 self.strides, 

1871 'padding': 

1872 self.padding, 

1873 'data_format': 

1874 self.data_format, 

1875 'depth_multiplier': 

1876 self.depth_multiplier, 

1877 'dilation_rate': 

1878 self.dilation_rate, 

1879 'activation': 

1880 activations.serialize(self.activation), 

1881 'use_bias': 

1882 self.use_bias, 

1883 'depthwise_initializer': 

1884 initializers.serialize(self.depthwise_initializer), 

1885 'pointwise_initializer': 

1886 initializers.serialize(self.pointwise_initializer), 

1887 'bias_initializer': 

1888 initializers.serialize(self.bias_initializer), 

1889 'depthwise_regularizer': 

1890 regularizers.serialize(self.depthwise_regularizer), 

1891 'pointwise_regularizer': 

1892 regularizers.serialize(self.pointwise_regularizer), 

1893 'bias_regularizer': 

1894 regularizers.serialize(self.bias_regularizer), 

1895 'activity_regularizer': 

1896 regularizers.serialize(self.activity_regularizer), 

1897 'depthwise_constraint': 

1898 constraints.serialize(self.depthwise_constraint), 

1899 'pointwise_constraint': 

1900 constraints.serialize(self.pointwise_constraint), 

1901 'bias_constraint': 

1902 constraints.serialize(self.bias_constraint) 

1903 } 

1904 base_config = super(SeparableConv, self).get_config() 

1905 return dict(list(base_config.items()) + list(config.items())) 

1906 

1907 

1908@keras_export('keras.layers.SeparableConv1D', 

1909 'keras.layers.SeparableConvolution1D') 

1910class SeparableConv1D(SeparableConv): 

1911 """Depthwise separable 1D convolution. 

1912 

1913 This layer performs a depthwise convolution that acts separately on 

1914 channels, followed by a pointwise convolution that mixes channels. 

1915 If `use_bias` is True and a bias initializer is provided, 

1916 it adds a bias vector to the output. 

1917 It then optionally applies an activation function to produce the final output. 

1918 

1919 Args: 

1920 filters: Integer, the dimensionality of the output space (i.e. the number 

1921 of filters in the convolution). 

1922 kernel_size: A single integer specifying the spatial 

1923 dimensions of the filters. 

1924 strides: A single integer specifying the strides 

1925 of the convolution. 

1926 Specifying any `stride` value != 1 is incompatible with specifying 

1927 any `dilation_rate` value != 1. 

1928 padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive). 

1929 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

1930 to the left/right or up/down of the input such that output has the same 

1931 height/width dimension as the input. `"causal"` results in causal 

1932 (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`. 

1933 data_format: A string, one of `channels_last` (default) or `channels_first`. 

1934 The ordering of the dimensions in the inputs. 

1935 `channels_last` corresponds to inputs with shape 

1936 `(batch_size, length, channels)` while `channels_first` corresponds to 

1937 inputs with shape `(batch_size, channels, length)`. 

1938 dilation_rate: A single integer, specifying 

1939 the dilation rate to use for dilated convolution. 

1940 Currently, specifying any `dilation_rate` value != 1 is 

1941 incompatible with specifying any stride value != 1. 

1942 depth_multiplier: The number of depthwise convolution output channels for 

1943 each input channel. The total number of depthwise convolution output 

1944 channels will be equal to `num_filters_in * depth_multiplier`. 

1945 activation: Activation function to use. 

1946 If you don't specify anything, no activation is applied ( 

1947 see `keras.activations`). 

1948 use_bias: Boolean, whether the layer uses a bias. 

1949 depthwise_initializer: An initializer for the depthwise convolution kernel ( 

1950 see `keras.initializers`). If None, then the default initializer ( 

1951 'glorot_uniform') will be used. 

1952 pointwise_initializer: An initializer for the pointwise convolution kernel ( 

1953 see `keras.initializers`). If None, then the default initializer  

1954 ('glorot_uniform') will be used. 

1955 bias_initializer: An initializer for the bias vector. If None, the default 

1956 initializer ('zeros') will be used (see `keras.initializers`). 

1957 depthwise_regularizer: Optional regularizer for the depthwise 

1958 convolution kernel (see `keras.regularizers`). 

1959 pointwise_regularizer: Optional regularizer for the pointwise 

1960 convolution kernel (see `keras.regularizers`). 

1961 bias_regularizer: Optional regularizer for the bias vector ( 

1962 see `keras.regularizers`). 

1963 activity_regularizer: Optional regularizer function for the output ( 

1964 see `keras.regularizers`). 

1965 depthwise_constraint: Optional projection function to be applied to the 

1966 depthwise kernel after being updated by an `Optimizer` (e.g. used for 

1967 norm constraints or value constraints for layer weights). The function 

1968 must take as input the unprojected variable and must return the 

1969 projected variable (which must have the same shape). Constraints are 

1970 not safe to use when doing asynchronous distributed training ( 

1971 see `keras.constraints`). 

1972 pointwise_constraint: Optional projection function to be applied to the 

1973 pointwise kernel after being updated by an `Optimizer` ( 

1974 see `keras.constraints`). 

1975 bias_constraint: Optional projection function to be applied to the 

1976 bias after being updated by an `Optimizer` ( 

1977 see `keras.constraints`). 

1978 trainable: Boolean, if `True` the weights of this layer will be marked as 

1979 trainable (and listed in `layer.trainable_weights`). 

1980 

1981 Input shape: 

1982 3D tensor with shape: 

1983 `(batch_size, channels, steps)` if data_format='channels_first' 

1984 or 5D tensor with shape: 

1985 `(batch_size, steps, channels)` if data_format='channels_last'. 

1986 

1987 Output shape: 

1988 3D tensor with shape: 

1989 `(batch_size, filters, new_steps)` if data_format='channels_first' 

1990 or 3D tensor with shape: 

1991 `(batch_size, new_steps, filters)` if data_format='channels_last'. 

1992 `new_steps` value might have changed due to padding or strides. 

1993 

1994 Returns: 

1995 A tensor of rank 3 representing 

1996 `activation(separableconv1d(inputs, kernel) + bias)`. 

1997 

1998 Raises: 

1999 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

2000 """ 

2001 

2002 def __init__(self, 

2003 filters, 

2004 kernel_size, 

2005 strides=1, 

2006 padding='valid', 

2007 data_format=None, 

2008 dilation_rate=1, 

2009 depth_multiplier=1, 

2010 activation=None, 

2011 use_bias=True, 

2012 depthwise_initializer='glorot_uniform', 

2013 pointwise_initializer='glorot_uniform', 

2014 bias_initializer='zeros', 

2015 depthwise_regularizer=None, 

2016 pointwise_regularizer=None, 

2017 bias_regularizer=None, 

2018 activity_regularizer=None, 

2019 depthwise_constraint=None, 

2020 pointwise_constraint=None, 

2021 bias_constraint=None, 

2022 **kwargs): 

2023 super(SeparableConv1D, self).__init__( 

2024 rank=1, 

2025 filters=filters, 

2026 kernel_size=kernel_size, 

2027 strides=strides, 

2028 padding=padding, 

2029 data_format=data_format, 

2030 dilation_rate=dilation_rate, 

2031 depth_multiplier=depth_multiplier, 

2032 activation=activations.get(activation), 

2033 use_bias=use_bias, 

2034 depthwise_initializer=initializers.get(depthwise_initializer), 

2035 pointwise_initializer=initializers.get(pointwise_initializer), 

2036 bias_initializer=initializers.get(bias_initializer), 

2037 depthwise_regularizer=regularizers.get(depthwise_regularizer), 

2038 pointwise_regularizer=regularizers.get(pointwise_regularizer), 

2039 bias_regularizer=regularizers.get(bias_regularizer), 

2040 activity_regularizer=regularizers.get(activity_regularizer), 

2041 depthwise_constraint=constraints.get(depthwise_constraint), 

2042 pointwise_constraint=constraints.get(pointwise_constraint), 

2043 bias_constraint=constraints.get(bias_constraint), 

2044 **kwargs) 

2045 

2046 def call(self, inputs): 

2047 if self.padding == 'causal': 

2048 inputs = array_ops.pad(inputs, self._compute_causal_padding(inputs)) 

2049 if self.data_format == 'channels_last': 

2050 strides = (1,) + self.strides * 2 + (1,) 

2051 spatial_start_dim = 1 

2052 else: 

2053 strides = (1, 1) + self.strides * 2 

2054 spatial_start_dim = 2 

2055 

2056 # Explicitly broadcast inputs and kernels to 4D. 

2057 # TODO(fchollet): refactor when a native separable_conv1d op is available. 

2058 inputs = array_ops.expand_dims(inputs, spatial_start_dim) 

2059 depthwise_kernel = array_ops.expand_dims(self.depthwise_kernel, 0) 

2060 pointwise_kernel = array_ops.expand_dims(self.pointwise_kernel, 0) 

2061 dilation_rate = (1,) + self.dilation_rate 

2062 

2063 if self.padding == 'causal': 

2064 op_padding = 'valid' 

2065 else: 

2066 op_padding = self.padding 

2067 outputs = nn.separable_conv2d( 

2068 inputs, 

2069 depthwise_kernel, 

2070 pointwise_kernel, 

2071 strides=strides, 

2072 padding=op_padding.upper(), 

2073 rate=dilation_rate, 

2074 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

2075 

2076 if self.use_bias: 

2077 outputs = nn.bias_add( 

2078 outputs, 

2079 self.bias, 

2080 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

2081 

2082 outputs = array_ops.squeeze(outputs, [spatial_start_dim]) 

2083 

2084 if self.activation is not None: 

2085 return self.activation(outputs) 

2086 return outputs 

2087 

2088 

2089@keras_export('keras.layers.SeparableConv2D', 

2090 'keras.layers.SeparableConvolution2D') 

2091class SeparableConv2D(SeparableConv): 

2092 """Depthwise separable 2D convolution. 

2093 

2094 Separable convolutions consist of first performing 

2095 a depthwise spatial convolution 

2096 (which acts on each input channel separately) 

2097 followed by a pointwise convolution which mixes the resulting 

2098 output channels. The `depth_multiplier` argument controls how many 

2099 output channels are generated per input channel in the depthwise step. 

2100 

2101 Intuitively, separable convolutions can be understood as 

2102 a way to factorize a convolution kernel into two smaller kernels, 

2103 or as an extreme version of an Inception block. 

2104 

2105 Args: 

2106 filters: Integer, the dimensionality of the output space 

2107 (i.e. the number of output filters in the convolution). 

2108 kernel_size: An integer or tuple/list of 2 integers, specifying the 

2109 height and width of the 2D convolution window. 

2110 Can be a single integer to specify the same value for 

2111 all spatial dimensions. 

2112 strides: An integer or tuple/list of 2 integers, 

2113 specifying the strides of the convolution along the height and width. 

2114 Can be a single integer to specify the same value for 

2115 all spatial dimensions. Current implementation only supports equal  

2116 length strides in the row and column dimensions. 

2117 Specifying any stride value != 1 is incompatible with specifying 

2118 any `dilation_rate` value != 1. 

2119 padding: one of `"valid"` or `"same"` (case-insensitive). 

2120 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

2121 to the left/right or up/down of the input such that output has the same 

2122 height/width dimension as the input. 

2123 data_format: A string, 

2124 one of `channels_last` (default) or `channels_first`. 

2125 The ordering of the dimensions in the inputs. 

2126 `channels_last` corresponds to inputs with shape 

2127 `(batch_size, height, width, channels)` while `channels_first` 

2128 corresponds to inputs with shape 

2129 `(batch_size, channels, height, width)`. 

2130 It defaults to the `image_data_format` value found in your 

2131 Keras config file at `~/.keras/keras.json`. 

2132 If you never set it, then it will be "channels_last". 

2133 dilation_rate: An integer or tuple/list of 2 integers, specifying 

2134 the dilation rate to use for dilated convolution. 

2135 Currently, specifying any `dilation_rate` value != 1 is 

2136 incompatible with specifying any `strides` value != 1. 

2137 depth_multiplier: The number of depthwise convolution output channels 

2138 for each input channel. 

2139 The total number of depthwise convolution output 

2140 channels will be equal to `filters_in * depth_multiplier`. 

2141 activation: Activation function to use. 

2142 If you don't specify anything, no activation is applied ( 

2143 see `keras.activations`). 

2144 use_bias: Boolean, whether the layer uses a bias vector. 

2145 depthwise_initializer: An initializer for the depthwise convolution kernel ( 

2146 see `keras.initializers`). If None, then the default initializer ( 

2147 'glorot_uniform') will be used. 

2148 pointwise_initializer: An initializer for the pointwise convolution kernel ( 

2149 see `keras.initializers`). If None, then the default initializer  

2150 ('glorot_uniform') will be used. 

2151 bias_initializer: An initializer for the bias vector. If None, the default 

2152 initializer ('zeros') will be used (see `keras.initializers`). 

2153 depthwise_regularizer: Regularizer function applied to 

2154 the depthwise kernel matrix (see `keras.regularizers`). 

2155 pointwise_regularizer: Regularizer function applied to 

2156 the pointwise kernel matrix (see `keras.regularizers`). 

2157 bias_regularizer: Regularizer function applied to the bias vector ( 

2158 see `keras.regularizers`). 

2159 activity_regularizer: Regularizer function applied to 

2160 the output of the layer (its "activation") ( 

2161 see `keras.regularizers`). 

2162 depthwise_constraint: Constraint function applied to 

2163 the depthwise kernel matrix ( 

2164 see `keras.constraints`). 

2165 pointwise_constraint: Constraint function applied to 

2166 the pointwise kernel matrix ( 

2167 see `keras.constraints`). 

2168 bias_constraint: Constraint function applied to the bias vector ( 

2169 see `keras.constraints`). 

2170 

2171 Input shape: 

2172 4D tensor with shape: 

2173 `(batch_size, channels, rows, cols)` if data_format='channels_first' 

2174 or 4D tensor with shape: 

2175 `(batch_size, rows, cols, channels)` if data_format='channels_last'. 

2176 

2177 Output shape: 

2178 4D tensor with shape: 

2179 `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first' 

2180 or 4D tensor with shape: 

2181 `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'. 

2182 `rows` and `cols` values might have changed due to padding. 

2183 

2184 Returns: 

2185 A tensor of rank 4 representing 

2186 `activation(separableconv2d(inputs, kernel) + bias)`. 

2187 

2188 Raises: 

2189 ValueError: if `padding` is "causal". 

2190 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

2191 """ 

2192 

2193 def __init__(self, 

2194 filters, 

2195 kernel_size, 

2196 strides=(1, 1), 

2197 padding='valid', 

2198 data_format=None, 

2199 dilation_rate=(1, 1), 

2200 depth_multiplier=1, 

2201 activation=None, 

2202 use_bias=True, 

2203 depthwise_initializer='glorot_uniform', 

2204 pointwise_initializer='glorot_uniform', 

2205 bias_initializer='zeros', 

2206 depthwise_regularizer=None, 

2207 pointwise_regularizer=None, 

2208 bias_regularizer=None, 

2209 activity_regularizer=None, 

2210 depthwise_constraint=None, 

2211 pointwise_constraint=None, 

2212 bias_constraint=None, 

2213 **kwargs): 

2214 super(SeparableConv2D, self).__init__( 

2215 rank=2, 

2216 filters=filters, 

2217 kernel_size=kernel_size, 

2218 strides=strides, 

2219 padding=padding, 

2220 data_format=data_format, 

2221 dilation_rate=dilation_rate, 

2222 depth_multiplier=depth_multiplier, 

2223 activation=activations.get(activation), 

2224 use_bias=use_bias, 

2225 depthwise_initializer=initializers.get(depthwise_initializer), 

2226 pointwise_initializer=initializers.get(pointwise_initializer), 

2227 bias_initializer=initializers.get(bias_initializer), 

2228 depthwise_regularizer=regularizers.get(depthwise_regularizer), 

2229 pointwise_regularizer=regularizers.get(pointwise_regularizer), 

2230 bias_regularizer=regularizers.get(bias_regularizer), 

2231 activity_regularizer=regularizers.get(activity_regularizer), 

2232 depthwise_constraint=constraints.get(depthwise_constraint), 

2233 pointwise_constraint=constraints.get(pointwise_constraint), 

2234 bias_constraint=constraints.get(bias_constraint), 

2235 **kwargs) 

2236 

2237 def call(self, inputs): 

2238 # Apply the actual ops. 

2239 if self.data_format == 'channels_last': 

2240 strides = (1,) + self.strides + (1,) 

2241 else: 

2242 strides = (1, 1) + self.strides 

2243 outputs = nn.separable_conv2d( 

2244 inputs, 

2245 self.depthwise_kernel, 

2246 self.pointwise_kernel, 

2247 strides=strides, 

2248 padding=self.padding.upper(), 

2249 rate=self.dilation_rate, 

2250 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

2251 

2252 if self.use_bias: 

2253 outputs = nn.bias_add( 

2254 outputs, 

2255 self.bias, 

2256 data_format=conv_utils.convert_data_format(self.data_format, ndim=4)) 

2257 

2258 if self.activation is not None: 

2259 return self.activation(outputs) 

2260 return outputs 

2261 

2262 

2263@keras_export('keras.layers.DepthwiseConv2D') 

2264class DepthwiseConv2D(Conv2D): 

2265 """Depthwise 2D convolution. 

2266 

2267 Depthwise convolution is a type of convolution in which a single convolutional 

2268 filter is apply to each input channel (i.e. in a depthwise way). 

2269 You can understand depthwise convolution as being 

2270 the first step in a depthwise separable convolution. 

2271 

2272 It is implemented via the following steps: 

2273 

2274 - Split the input into individual channels. 

2275 - Convolve each input with the layer's kernel (called a depthwise kernel). 

2276 - Stack the convolved outputs together (along the channels axis). 

2277 

2278 Unlike a regular 2D convolution, depthwise convolution does not mix 

2279 information across different input channels. 

2280 

2281 The `depth_multiplier` argument controls how many 

2282 output channels are generated per input channel in the depthwise step. 

2283 

2284 Args: 

2285 kernel_size: An integer or tuple/list of 2 integers, specifying the 

2286 height and width of the 2D convolution window. 

2287 Can be a single integer to specify the same value for 

2288 all spatial dimensions. 

2289 strides: An integer or tuple/list of 2 integers, 

2290 specifying the strides of the convolution along the height and width. 

2291 Can be a single integer to specify the same value for 

2292 all spatial dimensions. 

2293 Specifying any stride value != 1 is incompatible with specifying 

2294 any `dilation_rate` value != 1. 

2295 padding: one of `'valid'` or `'same'` (case-insensitive). 

2296 `"valid"` means no padding. `"same"` results in padding with zeros evenly 

2297 to the left/right or up/down of the input such that output has the same 

2298 height/width dimension as the input. 

2299 depth_multiplier: The number of depthwise convolution output channels 

2300 for each input channel. 

2301 The total number of depthwise convolution output 

2302 channels will be equal to `filters_in * depth_multiplier`. 

2303 data_format: A string, 

2304 one of `channels_last` (default) or `channels_first`. 

2305 The ordering of the dimensions in the inputs. 

2306 `channels_last` corresponds to inputs with shape 

2307 `(batch_size, height, width, channels)` while `channels_first` 

2308 corresponds to inputs with shape 

2309 `(batch_size, channels, height, width)`. 

2310 It defaults to the `image_data_format` value found in your 

2311 Keras config file at `~/.keras/keras.json`. 

2312 If you never set it, then it will be 'channels_last'. 

2313 dilation_rate: An integer or tuple/list of 2 integers, specifying 

2314 the dilation rate to use for dilated convolution. 

2315 Currently, specifying any `dilation_rate` value != 1 is 

2316 incompatible with specifying any `strides` value != 1. 

2317 activation: Activation function to use. 

2318 If you don't specify anything, no activation is applied ( 

2319 see `keras.activations`). 

2320 use_bias: Boolean, whether the layer uses a bias vector. 

2321 depthwise_initializer: Initializer for the depthwise kernel matrix ( 

2322 see `keras.initializers`). If None, the default initializer ( 

2323 'glorot_uniform') will be used. 

2324 bias_initializer: Initializer for the bias vector ( 

2325 see `keras.initializers`). If None, the default initializer ( 

2326 'zeros') will bs used. 

2327 depthwise_regularizer: Regularizer function applied to 

2328 the depthwise kernel matrix (see `keras.regularizers`). 

2329 bias_regularizer: Regularizer function applied to the bias vector ( 

2330 see `keras.regularizers`). 

2331 activity_regularizer: Regularizer function applied to 

2332 the output of the layer (its 'activation') ( 

2333 see `keras.regularizers`). 

2334 depthwise_constraint: Constraint function applied to 

2335 the depthwise kernel matrix ( 

2336 see `keras.constraints`). 

2337 bias_constraint: Constraint function applied to the bias vector ( 

2338 see `keras.constraints`). 

2339 

2340 Input shape: 

2341 4D tensor with shape: 

2342 `[batch_size, channels, rows, cols]` if data_format='channels_first' 

2343 or 4D tensor with shape: 

2344 `[batch_size, rows, cols, channels]` if data_format='channels_last'. 

2345 

2346 Output shape: 

2347 4D tensor with shape: 

2348 `[batch_size, channels * depth_multiplier, new_rows, new_cols]` if 

2349 data_format='channels_first' or 4D tensor with shape: 

2350 `[batch_size, new_rows, new_cols, channels * depth_multiplier]` if 

2351 data_format='channels_last'. `rows` and `cols` values might have 

2352 changed due to padding. 

2353 

2354 Returns: 

2355 A tensor of rank 4 representing 

2356 `activation(depthwiseconv2d(inputs, kernel) + bias)`. 

2357 

2358 Raises: 

2359 ValueError: if `padding` is "causal". 

2360 ValueError: when both `strides` > 1 and `dilation_rate` > 1. 

2361 """ 

2362 

2363 def __init__(self, 

2364 kernel_size, 

2365 strides=(1, 1), 

2366 padding='valid', 

2367 depth_multiplier=1, 

2368 data_format=None, 

2369 dilation_rate=(1, 1), 

2370 activation=None, 

2371 use_bias=True, 

2372 depthwise_initializer='glorot_uniform', 

2373 bias_initializer='zeros', 

2374 depthwise_regularizer=None, 

2375 bias_regularizer=None, 

2376 activity_regularizer=None, 

2377 depthwise_constraint=None, 

2378 bias_constraint=None, 

2379 **kwargs): 

2380 super(DepthwiseConv2D, self).__init__( 

2381 filters=None, 

2382 kernel_size=kernel_size, 

2383 strides=strides, 

2384 padding=padding, 

2385 data_format=data_format, 

2386 dilation_rate=dilation_rate, 

2387 activation=activation, 

2388 use_bias=use_bias, 

2389 bias_regularizer=bias_regularizer, 

2390 activity_regularizer=activity_regularizer, 

2391 bias_constraint=bias_constraint, 

2392 **kwargs) 

2393 self.depth_multiplier = depth_multiplier 

2394 self.depthwise_initializer = initializers.get(depthwise_initializer) 

2395 self.depthwise_regularizer = regularizers.get(depthwise_regularizer) 

2396 self.depthwise_constraint = constraints.get(depthwise_constraint) 

2397 self.bias_initializer = initializers.get(bias_initializer) 

2398 

2399 def build(self, input_shape): 

2400 if len(input_shape) < 4: 

2401 raise ValueError('Inputs to `DepthwiseConv2D` should have rank 4. ' 

2402 'Received input shape:', str(input_shape)) 

2403 input_shape = tensor_shape.TensorShape(input_shape) 

2404 channel_axis = self._get_channel_axis() 

2405 if input_shape.dims[channel_axis].value is None: 

2406 raise ValueError('The channel dimension of the inputs to ' 

2407 '`DepthwiseConv2D` ' 

2408 'should be defined. Found `None`.') 

2409 input_dim = int(input_shape[channel_axis]) 

2410 depthwise_kernel_shape = (self.kernel_size[0], 

2411 self.kernel_size[1], 

2412 input_dim, 

2413 self.depth_multiplier) 

2414 

2415 self.depthwise_kernel = self.add_weight( 

2416 shape=depthwise_kernel_shape, 

2417 initializer=self.depthwise_initializer, 

2418 name='depthwise_kernel', 

2419 regularizer=self.depthwise_regularizer, 

2420 constraint=self.depthwise_constraint) 

2421 

2422 if self.use_bias: 

2423 self.bias = self.add_weight(shape=(input_dim * self.depth_multiplier,), 

2424 initializer=self.bias_initializer, 

2425 name='bias', 

2426 regularizer=self.bias_regularizer, 

2427 constraint=self.bias_constraint) 

2428 else: 

2429 self.bias = None 

2430 # Set input spec. 

2431 self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim}) 

2432 self.built = True 

2433 

2434 def call(self, inputs): 

2435 outputs = backend.depthwise_conv2d( 

2436 inputs, 

2437 self.depthwise_kernel, 

2438 strides=self.strides, 

2439 padding=self.padding, 

2440 dilation_rate=self.dilation_rate, 

2441 data_format=self.data_format) 

2442 

2443 if self.use_bias: 

2444 outputs = backend.bias_add( 

2445 outputs, 

2446 self.bias, 

2447 data_format=self.data_format) 

2448 

2449 if self.activation is not None: 

2450 return self.activation(outputs) 

2451 

2452 return outputs 

2453 

2454 @tf_utils.shape_type_conversion 

2455 def compute_output_shape(self, input_shape): 

2456 if self.data_format == 'channels_first': 

2457 rows = input_shape[2] 

2458 cols = input_shape[3] 

2459 out_filters = input_shape[1] * self.depth_multiplier 

2460 elif self.data_format == 'channels_last': 

2461 rows = input_shape[1] 

2462 cols = input_shape[2] 

2463 out_filters = input_shape[3] * self.depth_multiplier 

2464 

2465 rows = conv_utils.conv_output_length(rows, self.kernel_size[0], 

2466 self.padding, 

2467 self.strides[0], 

2468 self.dilation_rate[0]) 

2469 cols = conv_utils.conv_output_length(cols, self.kernel_size[1], 

2470 self.padding, 

2471 self.strides[1], 

2472 self.dilation_rate[1]) 

2473 if self.data_format == 'channels_first': 

2474 return (input_shape[0], out_filters, rows, cols) 

2475 elif self.data_format == 'channels_last': 

2476 return (input_shape[0], rows, cols, out_filters) 

2477 

2478 def get_config(self): 

2479 config = super(DepthwiseConv2D, self).get_config() 

2480 config.pop('filters') 

2481 config.pop('kernel_initializer') 

2482 config.pop('kernel_regularizer') 

2483 config.pop('kernel_constraint') 

2484 config['depth_multiplier'] = self.depth_multiplier 

2485 config['depthwise_initializer'] = initializers.serialize( 

2486 self.depthwise_initializer) 

2487 config['depthwise_regularizer'] = regularizers.serialize( 

2488 self.depthwise_regularizer) 

2489 config['depthwise_constraint'] = constraints.serialize( 

2490 self.depthwise_constraint) 

2491 return config 

2492 

2493 

2494@keras_export('keras.layers.UpSampling1D') 

2495class UpSampling1D(Layer): 

2496 """Upsampling layer for 1D inputs. 

2497 

2498 Repeats each temporal step `size` times along the time axis. 

2499 

2500 Examples: 

2501 

2502 >>> input_shape = (2, 2, 3) 

2503 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

2504 >>> print(x) 

2505 [[[ 0 1 2] 

2506 [ 3 4 5]] 

2507 [[ 6 7 8] 

2508 [ 9 10 11]]] 

2509 >>> y = tf.keras.layers.UpSampling1D(size=2)(x) 

2510 >>> print(y) 

2511 tf.Tensor( 

2512 [[[ 0 1 2] 

2513 [ 0 1 2] 

2514 [ 3 4 5] 

2515 [ 3 4 5]] 

2516 [[ 6 7 8] 

2517 [ 6 7 8] 

2518 [ 9 10 11] 

2519 [ 9 10 11]]], shape=(2, 4, 3), dtype=int64) 

2520 

2521 Args: 

2522 size: Integer. Upsampling factor. 

2523 

2524 Input shape: 

2525 3D tensor with shape: `(batch_size, steps, features)`. 

2526 

2527 Output shape: 

2528 3D tensor with shape: `(batch_size, upsampled_steps, features)`. 

2529 """ 

2530 

2531 def __init__(self, size=2, **kwargs): 

2532 super(UpSampling1D, self).__init__(**kwargs) 

2533 self.size = int(size) 

2534 self.input_spec = InputSpec(ndim=3) 

2535 

2536 def compute_output_shape(self, input_shape): 

2537 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

2538 size = self.size * input_shape[1] if input_shape[1] is not None else None 

2539 return tensor_shape.TensorShape([input_shape[0], size, input_shape[2]]) 

2540 

2541 def call(self, inputs): 

2542 output = backend.repeat_elements(inputs, self.size, axis=1) 

2543 return output 

2544 

2545 def get_config(self): 

2546 config = {'size': self.size} 

2547 base_config = super(UpSampling1D, self).get_config() 

2548 return dict(list(base_config.items()) + list(config.items())) 

2549 

2550 

2551@keras_export('keras.layers.UpSampling2D') 

2552class UpSampling2D(Layer): 

2553 """Upsampling layer for 2D inputs. 

2554 

2555 Repeats the rows and columns of the data 

2556 by `size[0]` and `size[1]` respectively. 

2557 

2558 Examples: 

2559 

2560 >>> input_shape = (2, 2, 1, 3) 

2561 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

2562 >>> print(x) 

2563 [[[[ 0 1 2]] 

2564 [[ 3 4 5]]] 

2565 [[[ 6 7 8]] 

2566 [[ 9 10 11]]]] 

2567 >>> y = tf.keras.layers.UpSampling2D(size=(1, 2))(x) 

2568 >>> print(y) 

2569 tf.Tensor( 

2570 [[[[ 0 1 2] 

2571 [ 0 1 2]] 

2572 [[ 3 4 5] 

2573 [ 3 4 5]]] 

2574 [[[ 6 7 8] 

2575 [ 6 7 8]] 

2576 [[ 9 10 11] 

2577 [ 9 10 11]]]], shape=(2, 2, 2, 3), dtype=int64) 

2578 

2579 Args: 

2580 size: Int, or tuple of 2 integers. 

2581 The upsampling factors for rows and columns. 

2582 data_format: A string, 

2583 one of `channels_last` (default) or `channels_first`. 

2584 The ordering of the dimensions in the inputs. 

2585 `channels_last` corresponds to inputs with shape 

2586 `(batch_size, height, width, channels)` while `channels_first` 

2587 corresponds to inputs with shape 

2588 `(batch_size, channels, height, width)`. 

2589 It defaults to the `image_data_format` value found in your 

2590 Keras config file at `~/.keras/keras.json`. 

2591 If you never set it, then it will be "channels_last". 

2592 interpolation: A string, one of `nearest` or `bilinear`. 

2593 

2594 Input shape: 

2595 4D tensor with shape: 

2596 - If `data_format` is `"channels_last"`: 

2597 `(batch_size, rows, cols, channels)` 

2598 - If `data_format` is `"channels_first"`: 

2599 `(batch_size, channels, rows, cols)` 

2600 

2601 Output shape: 

2602 4D tensor with shape: 

2603 - If `data_format` is `"channels_last"`: 

2604 `(batch_size, upsampled_rows, upsampled_cols, channels)` 

2605 - If `data_format` is `"channels_first"`: 

2606 `(batch_size, channels, upsampled_rows, upsampled_cols)` 

2607 """ 

2608 

2609 def __init__(self, 

2610 size=(2, 2), 

2611 data_format=None, 

2612 interpolation='nearest', 

2613 **kwargs): 

2614 super(UpSampling2D, self).__init__(**kwargs) 

2615 self.data_format = conv_utils.normalize_data_format(data_format) 

2616 self.size = conv_utils.normalize_tuple(size, 2, 'size') 

2617 if interpolation not in {'nearest', 'bilinear'}: 

2618 raise ValueError('`interpolation` argument should be one of `"nearest"` ' 

2619 'or `"bilinear"`.') 

2620 self.interpolation = interpolation 

2621 self.input_spec = InputSpec(ndim=4) 

2622 

2623 def compute_output_shape(self, input_shape): 

2624 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

2625 if self.data_format == 'channels_first': 

2626 height = self.size[0] * input_shape[ 

2627 2] if input_shape[2] is not None else None 

2628 width = self.size[1] * input_shape[ 

2629 3] if input_shape[3] is not None else None 

2630 return tensor_shape.TensorShape( 

2631 [input_shape[0], input_shape[1], height, width]) 

2632 else: 

2633 height = self.size[0] * input_shape[ 

2634 1] if input_shape[1] is not None else None 

2635 width = self.size[1] * input_shape[ 

2636 2] if input_shape[2] is not None else None 

2637 return tensor_shape.TensorShape( 

2638 [input_shape[0], height, width, input_shape[3]]) 

2639 

2640 def call(self, inputs): 

2641 return backend.resize_images( 

2642 inputs, self.size[0], self.size[1], self.data_format, 

2643 interpolation=self.interpolation) 

2644 

2645 def get_config(self): 

2646 config = { 

2647 'size': self.size, 

2648 'data_format': self.data_format, 

2649 'interpolation': self.interpolation 

2650 } 

2651 base_config = super(UpSampling2D, self).get_config() 

2652 return dict(list(base_config.items()) + list(config.items())) 

2653 

2654 

2655@keras_export('keras.layers.UpSampling3D') 

2656class UpSampling3D(Layer): 

2657 """Upsampling layer for 3D inputs. 

2658 

2659 Repeats the 1st, 2nd and 3rd dimensions 

2660 of the data by `size[0]`, `size[1]` and `size[2]` respectively. 

2661 

2662 Examples: 

2663 

2664 >>> input_shape = (2, 1, 2, 1, 3) 

2665 >>> x = tf.constant(1, shape=input_shape) 

2666 >>> y = tf.keras.layers.UpSampling3D(size=2)(x) 

2667 >>> print(y.shape) 

2668 (2, 2, 4, 2, 3) 

2669 

2670 Args: 

2671 size: Int, or tuple of 3 integers. 

2672 The upsampling factors for dim1, dim2 and dim3. 

2673 data_format: A string, 

2674 one of `channels_last` (default) or `channels_first`. 

2675 The ordering of the dimensions in the inputs. 

2676 `channels_last` corresponds to inputs with shape 

2677 `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)` 

2678 while `channels_first` corresponds to inputs with shape 

2679 `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`. 

2680 It defaults to the `image_data_format` value found in your 

2681 Keras config file at `~/.keras/keras.json`. 

2682 If you never set it, then it will be "channels_last". 

2683 

2684 Input shape: 

2685 5D tensor with shape: 

2686 - If `data_format` is `"channels_last"`: 

2687 `(batch_size, dim1, dim2, dim3, channels)` 

2688 - If `data_format` is `"channels_first"`: 

2689 `(batch_size, channels, dim1, dim2, dim3)` 

2690 

2691 Output shape: 

2692 5D tensor with shape: 

2693 - If `data_format` is `"channels_last"`: 

2694 `(batch_size, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)` 

2695 - If `data_format` is `"channels_first"`: 

2696 `(batch_size, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)` 

2697 """ 

2698 

2699 def __init__(self, size=(2, 2, 2), data_format=None, **kwargs): 

2700 self.data_format = conv_utils.normalize_data_format(data_format) 

2701 self.size = conv_utils.normalize_tuple(size, 3, 'size') 

2702 self.input_spec = InputSpec(ndim=5) 

2703 super(UpSampling3D, self).__init__(**kwargs) 

2704 

2705 def compute_output_shape(self, input_shape): 

2706 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

2707 if self.data_format == 'channels_first': 

2708 dim1 = self.size[0] * input_shape[ 

2709 2] if input_shape[2] is not None else None 

2710 dim2 = self.size[1] * input_shape[ 

2711 3] if input_shape[3] is not None else None 

2712 dim3 = self.size[2] * input_shape[ 

2713 4] if input_shape[4] is not None else None 

2714 return tensor_shape.TensorShape( 

2715 [input_shape[0], input_shape[1], dim1, dim2, dim3]) 

2716 else: 

2717 dim1 = self.size[0] * input_shape[ 

2718 1] if input_shape[1] is not None else None 

2719 dim2 = self.size[1] * input_shape[ 

2720 2] if input_shape[2] is not None else None 

2721 dim3 = self.size[2] * input_shape[ 

2722 3] if input_shape[3] is not None else None 

2723 return tensor_shape.TensorShape( 

2724 [input_shape[0], dim1, dim2, dim3, input_shape[4]]) 

2725 

2726 def call(self, inputs): 

2727 return backend.resize_volumes( 

2728 inputs, self.size[0], self.size[1], self.size[2], self.data_format) 

2729 

2730 def get_config(self): 

2731 config = {'size': self.size, 'data_format': self.data_format} 

2732 base_config = super(UpSampling3D, self).get_config() 

2733 return dict(list(base_config.items()) + list(config.items())) 

2734 

2735 

2736@keras_export('keras.layers.ZeroPadding1D') 

2737class ZeroPadding1D(Layer): 

2738 """Zero-padding layer for 1D input (e.g. temporal sequence). 

2739 

2740 Examples: 

2741 

2742 >>> input_shape = (2, 2, 3) 

2743 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

2744 >>> print(x) 

2745 [[[ 0 1 2] 

2746 [ 3 4 5]] 

2747 [[ 6 7 8] 

2748 [ 9 10 11]]] 

2749 >>> y = tf.keras.layers.ZeroPadding1D(padding=2)(x) 

2750 >>> print(y) 

2751 tf.Tensor( 

2752 [[[ 0 0 0] 

2753 [ 0 0 0] 

2754 [ 0 1 2] 

2755 [ 3 4 5] 

2756 [ 0 0 0] 

2757 [ 0 0 0]] 

2758 [[ 0 0 0] 

2759 [ 0 0 0] 

2760 [ 6 7 8] 

2761 [ 9 10 11] 

2762 [ 0 0 0] 

2763 [ 0 0 0]]], shape=(2, 6, 3), dtype=int64) 

2764 

2765 Args: 

2766 padding: Int, or tuple of int (length 2), or dictionary. 

2767 - If int: 

2768 How many zeros to add at the beginning and end of 

2769 the padding dimension (axis 1). 

2770 - If tuple of int (length 2): 

2771 How many zeros to add at the beginning and the end of 

2772 the padding dimension (`(left_pad, right_pad)`). 

2773 

2774 Input shape: 

2775 3D tensor with shape `(batch_size, axis_to_pad, features)` 

2776 

2777 Output shape: 

2778 3D tensor with shape `(batch_size, padded_axis, features)` 

2779 """ 

2780 

2781 def __init__(self, padding=1, **kwargs): 

2782 super(ZeroPadding1D, self).__init__(**kwargs) 

2783 self.padding = conv_utils.normalize_tuple(padding, 2, 'padding') 

2784 self.input_spec = InputSpec(ndim=3) 

2785 

2786 def compute_output_shape(self, input_shape): 

2787 if input_shape[1] is not None: 

2788 length = input_shape[1] + self.padding[0] + self.padding[1] 

2789 else: 

2790 length = None 

2791 return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]]) 

2792 

2793 def call(self, inputs): 

2794 return backend.temporal_padding(inputs, padding=self.padding) 

2795 

2796 def get_config(self): 

2797 config = {'padding': self.padding} 

2798 base_config = super(ZeroPadding1D, self).get_config() 

2799 return dict(list(base_config.items()) + list(config.items())) 

2800 

2801 

2802@keras_export('keras.layers.ZeroPadding2D') 

2803class ZeroPadding2D(Layer): 

2804 """Zero-padding layer for 2D input (e.g. picture). 

2805 

2806 This layer can add rows and columns of zeros 

2807 at the top, bottom, left and right side of an image tensor. 

2808 

2809 Examples: 

2810 

2811 >>> input_shape = (1, 1, 2, 2) 

2812 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

2813 >>> print(x) 

2814 [[[[0 1] 

2815 [2 3]]]] 

2816 >>> y = tf.keras.layers.ZeroPadding2D(padding=1)(x) 

2817 >>> print(y) 

2818 tf.Tensor( 

2819 [[[[0 0] 

2820 [0 0] 

2821 [0 0] 

2822 [0 0]] 

2823 [[0 0] 

2824 [0 1] 

2825 [2 3] 

2826 [0 0]] 

2827 [[0 0] 

2828 [0 0] 

2829 [0 0] 

2830 [0 0]]]], shape=(1, 3, 4, 2), dtype=int64) 

2831 

2832 Args: 

2833 padding: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints. 

2834 - If int: the same symmetric padding 

2835 is applied to height and width. 

2836 - If tuple of 2 ints: 

2837 interpreted as two different 

2838 symmetric padding values for height and width: 

2839 `(symmetric_height_pad, symmetric_width_pad)`. 

2840 - If tuple of 2 tuples of 2 ints: 

2841 interpreted as 

2842 `((top_pad, bottom_pad), (left_pad, right_pad))` 

2843 data_format: A string, 

2844 one of `channels_last` (default) or `channels_first`. 

2845 The ordering of the dimensions in the inputs. 

2846 `channels_last` corresponds to inputs with shape 

2847 `(batch_size, height, width, channels)` while `channels_first` 

2848 corresponds to inputs with shape 

2849 `(batch_size, channels, height, width)`. 

2850 It defaults to the `image_data_format` value found in your 

2851 Keras config file at `~/.keras/keras.json`. 

2852 If you never set it, then it will be "channels_last". 

2853 

2854 Input shape: 

2855 4D tensor with shape: 

2856 - If `data_format` is `"channels_last"`: 

2857 `(batch_size, rows, cols, channels)` 

2858 - If `data_format` is `"channels_first"`: 

2859 `(batch_size, channels, rows, cols)` 

2860 

2861 Output shape: 

2862 4D tensor with shape: 

2863 - If `data_format` is `"channels_last"`: 

2864 `(batch_size, padded_rows, padded_cols, channels)` 

2865 - If `data_format` is `"channels_first"`: 

2866 `(batch_size, channels, padded_rows, padded_cols)` 

2867 """ 

2868 

2869 def __init__(self, padding=(1, 1), data_format=None, **kwargs): 

2870 super(ZeroPadding2D, self).__init__(**kwargs) 

2871 self.data_format = conv_utils.normalize_data_format(data_format) 

2872 if isinstance(padding, int): 

2873 self.padding = ((padding, padding), (padding, padding)) 

2874 elif hasattr(padding, '__len__'): 

2875 if len(padding) != 2: 

2876 raise ValueError('`padding` should have two elements. ' 

2877 'Found: ' + str(padding)) 

2878 height_padding = conv_utils.normalize_tuple(padding[0], 2, 

2879 '1st entry of padding') 

2880 width_padding = conv_utils.normalize_tuple(padding[1], 2, 

2881 '2nd entry of padding') 

2882 self.padding = (height_padding, width_padding) 

2883 else: 

2884 raise ValueError('`padding` should be either an int, ' 

2885 'a tuple of 2 ints ' 

2886 '(symmetric_height_pad, symmetric_width_pad), ' 

2887 'or a tuple of 2 tuples of 2 ints ' 

2888 '((top_pad, bottom_pad), (left_pad, right_pad)). ' 

2889 'Found: ' + str(padding)) 

2890 self.input_spec = InputSpec(ndim=4) 

2891 

2892 def compute_output_shape(self, input_shape): 

2893 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

2894 if self.data_format == 'channels_first': 

2895 if input_shape[2] is not None: 

2896 rows = input_shape[2] + self.padding[0][0] + self.padding[0][1] 

2897 else: 

2898 rows = None 

2899 if input_shape[3] is not None: 

2900 cols = input_shape[3] + self.padding[1][0] + self.padding[1][1] 

2901 else: 

2902 cols = None 

2903 return tensor_shape.TensorShape( 

2904 [input_shape[0], input_shape[1], rows, cols]) 

2905 elif self.data_format == 'channels_last': 

2906 if input_shape[1] is not None: 

2907 rows = input_shape[1] + self.padding[0][0] + self.padding[0][1] 

2908 else: 

2909 rows = None 

2910 if input_shape[2] is not None: 

2911 cols = input_shape[2] + self.padding[1][0] + self.padding[1][1] 

2912 else: 

2913 cols = None 

2914 return tensor_shape.TensorShape( 

2915 [input_shape[0], rows, cols, input_shape[3]]) 

2916 

2917 def call(self, inputs): 

2918 return backend.spatial_2d_padding( 

2919 inputs, padding=self.padding, data_format=self.data_format) 

2920 

2921 def get_config(self): 

2922 config = {'padding': self.padding, 'data_format': self.data_format} 

2923 base_config = super(ZeroPadding2D, self).get_config() 

2924 return dict(list(base_config.items()) + list(config.items())) 

2925 

2926 

2927@keras_export('keras.layers.ZeroPadding3D') 

2928class ZeroPadding3D(Layer): 

2929 """Zero-padding layer for 3D data (spatial or spatio-temporal). 

2930 

2931 Examples: 

2932 

2933 >>> input_shape = (1, 1, 2, 2, 3) 

2934 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

2935 >>> y = tf.keras.layers.ZeroPadding3D(padding=2)(x) 

2936 >>> print(y.shape) 

2937 (1, 5, 6, 6, 3) 

2938 

2939 Args: 

2940 padding: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints. 

2941 - If int: the same symmetric padding 

2942 is applied to height and width. 

2943 - If tuple of 3 ints: 

2944 interpreted as two different 

2945 symmetric padding values for height and width: 

2946 `(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad)`. 

2947 - If tuple of 3 tuples of 2 ints: 

2948 interpreted as 

2949 `((left_dim1_pad, right_dim1_pad), (left_dim2_pad, 

2950 right_dim2_pad), (left_dim3_pad, right_dim3_pad))` 

2951 data_format: A string, 

2952 one of `channels_last` (default) or `channels_first`. 

2953 The ordering of the dimensions in the inputs. 

2954 `channels_last` corresponds to inputs with shape 

2955 `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)` 

2956 while `channels_first` corresponds to inputs with shape 

2957 `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`. 

2958 It defaults to the `image_data_format` value found in your 

2959 Keras config file at `~/.keras/keras.json`. 

2960 If you never set it, then it will be "channels_last". 

2961 

2962 Input shape: 

2963 5D tensor with shape: 

2964 - If `data_format` is `"channels_last"`: 

2965 `(batch_size, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad, 

2966 depth)` 

2967 - If `data_format` is `"channels_first"`: 

2968 `(batch_size, depth, first_axis_to_pad, second_axis_to_pad, 

2969 third_axis_to_pad)` 

2970 

2971 Output shape: 

2972 5D tensor with shape: 

2973 - If `data_format` is `"channels_last"`: 

2974 `(batch_size, first_padded_axis, second_padded_axis, third_axis_to_pad, 

2975 depth)` 

2976 - If `data_format` is `"channels_first"`: 

2977 `(batch_size, depth, first_padded_axis, second_padded_axis, 

2978 third_axis_to_pad)` 

2979 """ 

2980 

2981 def __init__(self, padding=(1, 1, 1), data_format=None, **kwargs): 

2982 super(ZeroPadding3D, self).__init__(**kwargs) 

2983 self.data_format = conv_utils.normalize_data_format(data_format) 

2984 if isinstance(padding, int): 

2985 self.padding = ((padding, padding), (padding, padding), (padding, 

2986 padding)) 

2987 elif hasattr(padding, '__len__'): 

2988 if len(padding) != 3: 

2989 raise ValueError('`padding` should have 3 elements. ' 

2990 'Found: ' + str(padding)) 

2991 dim1_padding = conv_utils.normalize_tuple(padding[0], 2, 

2992 '1st entry of padding') 

2993 dim2_padding = conv_utils.normalize_tuple(padding[1], 2, 

2994 '2nd entry of padding') 

2995 dim3_padding = conv_utils.normalize_tuple(padding[2], 2, 

2996 '3rd entry of padding') 

2997 self.padding = (dim1_padding, dim2_padding, dim3_padding) 

2998 else: 

2999 raise ValueError( 

3000 '`padding` should be either an int, ' 

3001 'a tuple of 3 ints ' 

3002 '(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad), ' 

3003 'or a tuple of 3 tuples of 2 ints ' 

3004 '((left_dim1_pad, right_dim1_pad),' 

3005 ' (left_dim2_pad, right_dim2_pad),' 

3006 ' (left_dim3_pad, right_dim2_pad)). ' 

3007 'Found: ' + str(padding)) 

3008 self.input_spec = InputSpec(ndim=5) 

3009 

3010 def compute_output_shape(self, input_shape): 

3011 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

3012 if self.data_format == 'channels_first': 

3013 if input_shape[2] is not None: 

3014 dim1 = input_shape[2] + self.padding[0][0] + self.padding[0][1] 

3015 else: 

3016 dim1 = None 

3017 if input_shape[3] is not None: 

3018 dim2 = input_shape[3] + self.padding[1][0] + self.padding[1][1] 

3019 else: 

3020 dim2 = None 

3021 if input_shape[4] is not None: 

3022 dim3 = input_shape[4] + self.padding[2][0] + self.padding[2][1] 

3023 else: 

3024 dim3 = None 

3025 return tensor_shape.TensorShape( 

3026 [input_shape[0], input_shape[1], dim1, dim2, dim3]) 

3027 elif self.data_format == 'channels_last': 

3028 if input_shape[1] is not None: 

3029 dim1 = input_shape[1] + self.padding[0][0] + self.padding[0][1] 

3030 else: 

3031 dim1 = None 

3032 if input_shape[2] is not None: 

3033 dim2 = input_shape[2] + self.padding[1][0] + self.padding[1][1] 

3034 else: 

3035 dim2 = None 

3036 if input_shape[3] is not None: 

3037 dim3 = input_shape[3] + self.padding[2][0] + self.padding[2][1] 

3038 else: 

3039 dim3 = None 

3040 return tensor_shape.TensorShape( 

3041 [input_shape[0], dim1, dim2, dim3, input_shape[4]]) 

3042 

3043 def call(self, inputs): 

3044 return backend.spatial_3d_padding( 

3045 inputs, padding=self.padding, data_format=self.data_format) 

3046 

3047 def get_config(self): 

3048 config = {'padding': self.padding, 'data_format': self.data_format} 

3049 base_config = super(ZeroPadding3D, self).get_config() 

3050 return dict(list(base_config.items()) + list(config.items())) 

3051 

3052 

3053@keras_export('keras.layers.Cropping1D') 

3054class Cropping1D(Layer): 

3055 """Cropping layer for 1D input (e.g. temporal sequence). 

3056 

3057 It crops along the time dimension (axis 1). 

3058 

3059 Examples: 

3060 

3061 >>> input_shape = (2, 3, 2) 

3062 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

3063 >>> print(x) 

3064 [[[ 0 1] 

3065 [ 2 3] 

3066 [ 4 5]] 

3067 [[ 6 7] 

3068 [ 8 9] 

3069 [10 11]]] 

3070 >>> y = tf.keras.layers.Cropping1D(cropping=1)(x) 

3071 >>> print(y) 

3072 tf.Tensor( 

3073 [[[2 3]] 

3074 [[8 9]]], shape=(2, 1, 2), dtype=int64) 

3075 

3076 Args: 

3077 cropping: Int or tuple of int (length 2) 

3078 How many units should be trimmed off at the beginning and end of 

3079 the cropping dimension (axis 1). 

3080 If a single int is provided, the same value will be used for both. 

3081 

3082 Input shape: 

3083 3D tensor with shape `(batch_size, axis_to_crop, features)` 

3084 

3085 Output shape: 

3086 3D tensor with shape `(batch_size, cropped_axis, features)` 

3087 """ 

3088 

3089 def __init__(self, cropping=(1, 1), **kwargs): 

3090 super(Cropping1D, self).__init__(**kwargs) 

3091 self.cropping = conv_utils.normalize_tuple(cropping, 2, 'cropping') 

3092 self.input_spec = InputSpec(ndim=3) 

3093 

3094 def compute_output_shape(self, input_shape): 

3095 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

3096 if input_shape[1] is not None: 

3097 length = input_shape[1] - self.cropping[0] - self.cropping[1] 

3098 else: 

3099 length = None 

3100 return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]]) 

3101 

3102 def call(self, inputs): 

3103 if self.cropping[1] == 0: 

3104 return inputs[:, self.cropping[0]:, :] 

3105 else: 

3106 return inputs[:, self.cropping[0]:-self.cropping[1], :] 

3107 

3108 def get_config(self): 

3109 config = {'cropping': self.cropping} 

3110 base_config = super(Cropping1D, self).get_config() 

3111 return dict(list(base_config.items()) + list(config.items())) 

3112 

3113 

3114@keras_export('keras.layers.Cropping2D') 

3115class Cropping2D(Layer): 

3116 """Cropping layer for 2D input (e.g. picture). 

3117 

3118 It crops along spatial dimensions, i.e. height and width. 

3119 

3120 Examples: 

3121 

3122 >>> input_shape = (2, 28, 28, 3) 

3123 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

3124 >>> y = tf.keras.layers.Cropping2D(cropping=((2, 2), (4, 4)))(x) 

3125 >>> print(y.shape) 

3126 (2, 24, 20, 3) 

3127 

3128 Args: 

3129 cropping: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints. 

3130 - If int: the same symmetric cropping 

3131 is applied to height and width. 

3132 - If tuple of 2 ints: 

3133 interpreted as two different 

3134 symmetric cropping values for height and width: 

3135 `(symmetric_height_crop, symmetric_width_crop)`. 

3136 - If tuple of 2 tuples of 2 ints: 

3137 interpreted as 

3138 `((top_crop, bottom_crop), (left_crop, right_crop))` 

3139 data_format: A string, 

3140 one of `channels_last` (default) or `channels_first`. 

3141 The ordering of the dimensions in the inputs. 

3142 `channels_last` corresponds to inputs with shape 

3143 `(batch_size, height, width, channels)` while `channels_first` 

3144 corresponds to inputs with shape 

3145 `(batch_size, channels, height, width)`. 

3146 It defaults to the `image_data_format` value found in your 

3147 Keras config file at `~/.keras/keras.json`. 

3148 If you never set it, then it will be "channels_last". 

3149 

3150 Input shape: 

3151 4D tensor with shape: 

3152 - If `data_format` is `"channels_last"`: 

3153 `(batch_size, rows, cols, channels)` 

3154 - If `data_format` is `"channels_first"`: 

3155 `(batch_size, channels, rows, cols)` 

3156 

3157 Output shape: 

3158 4D tensor with shape: 

3159 - If `data_format` is `"channels_last"`: 

3160 `(batch_size, cropped_rows, cropped_cols, channels)` 

3161 - If `data_format` is `"channels_first"`: 

3162 `(batch_size, channels, cropped_rows, cropped_cols)` 

3163 """ 

3164 

3165 def __init__(self, cropping=((0, 0), (0, 0)), data_format=None, **kwargs): 

3166 super(Cropping2D, self).__init__(**kwargs) 

3167 self.data_format = conv_utils.normalize_data_format(data_format) 

3168 if isinstance(cropping, int): 

3169 self.cropping = ((cropping, cropping), (cropping, cropping)) 

3170 elif hasattr(cropping, '__len__'): 

3171 if len(cropping) != 2: 

3172 raise ValueError('`cropping` should have two elements. ' 

3173 'Found: ' + str(cropping)) 

3174 height_cropping = conv_utils.normalize_tuple(cropping[0], 2, 

3175 '1st entry of cropping') 

3176 width_cropping = conv_utils.normalize_tuple(cropping[1], 2, 

3177 '2nd entry of cropping') 

3178 self.cropping = (height_cropping, width_cropping) 

3179 else: 

3180 raise ValueError('`cropping` should be either an int, ' 

3181 'a tuple of 2 ints ' 

3182 '(symmetric_height_crop, symmetric_width_crop), ' 

3183 'or a tuple of 2 tuples of 2 ints ' 

3184 '((top_crop, bottom_crop), (left_crop, right_crop)). ' 

3185 'Found: ' + str(cropping)) 

3186 self.input_spec = InputSpec(ndim=4) 

3187 

3188 def compute_output_shape(self, input_shape): 

3189 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

3190 # pylint: disable=invalid-unary-operand-type 

3191 if self.data_format == 'channels_first': 

3192 return tensor_shape.TensorShape([ 

3193 input_shape[0], input_shape[1], 

3194 input_shape[2] - self.cropping[0][0] - self.cropping[0][1] 

3195 if input_shape[2] else None, 

3196 input_shape[3] - self.cropping[1][0] - self.cropping[1][1] 

3197 if input_shape[3] else None 

3198 ]) 

3199 else: 

3200 return tensor_shape.TensorShape([ 

3201 input_shape[0], 

3202 input_shape[1] - self.cropping[0][0] - self.cropping[0][1] 

3203 if input_shape[1] else None, 

3204 input_shape[2] - self.cropping[1][0] - self.cropping[1][1] 

3205 if input_shape[2] else None, input_shape[3] 

3206 ]) 

3207 # pylint: enable=invalid-unary-operand-type 

3208 

3209 def call(self, inputs): 

3210 # pylint: disable=invalid-unary-operand-type 

3211 if self.data_format == 'channels_first': 

3212 if self.cropping[0][1] == self.cropping[1][1] == 0: 

3213 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:] 

3214 elif self.cropping[0][1] == 0: 

3215 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]: 

3216 -self.cropping[1][1]] 

3217 elif self.cropping[1][1] == 0: 

3218 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], 

3219 self.cropping[1][0]:] 

3220 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], 

3221 self.cropping[1][0]:-self.cropping[1][1]] 

3222 else: 

3223 if self.cropping[0][1] == self.cropping[1][1] == 0: 

3224 return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, :] 

3225 elif self.cropping[0][1] == 0: 

3226 return inputs[:, self.cropping[0][0]:, self.cropping[1][0]: 

3227 -self.cropping[1][1], :] 

3228 elif self.cropping[1][1] == 0: 

3229 return inputs[:, self.cropping[0][0]:-self.cropping[0][1], 

3230 self.cropping[1][0]:, :] 

3231 return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[ 

3232 1][0]:-self.cropping[1][1], :] # pylint: disable=invalid-unary-operand-type 

3233 # pylint: enable=invalid-unary-operand-type 

3234 

3235 def get_config(self): 

3236 config = {'cropping': self.cropping, 'data_format': self.data_format} 

3237 base_config = super(Cropping2D, self).get_config() 

3238 return dict(list(base_config.items()) + list(config.items())) 

3239 

3240 

3241@keras_export('keras.layers.Cropping3D') 

3242class Cropping3D(Layer): 

3243 """Cropping layer for 3D data (e.g. spatial or spatio-temporal). 

3244 

3245 Examples: 

3246 

3247 >>> input_shape = (2, 28, 28, 10, 3) 

3248 >>> x = np.arange(np.prod(input_shape)).reshape(input_shape) 

3249 >>> y = tf.keras.layers.Cropping3D(cropping=(2, 4, 2))(x) 

3250 >>> print(y.shape) 

3251 (2, 24, 20, 6, 3) 

3252 

3253 Args: 

3254 cropping: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints. 

3255 - If int: the same symmetric cropping 

3256 is applied to depth, height, and width. 

3257 - If tuple of 3 ints: interpreted as two different 

3258 symmetric cropping values for depth, height, and width: 

3259 `(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop)`. 

3260 - If tuple of 3 tuples of 2 ints: interpreted as 

3261 `((left_dim1_crop, right_dim1_crop), (left_dim2_crop, 

3262 right_dim2_crop), (left_dim3_crop, right_dim3_crop))` 

3263 data_format: A string, 

3264 one of `channels_last` (default) or `channels_first`. 

3265 The ordering of the dimensions in the inputs. 

3266 `channels_last` corresponds to inputs with shape 

3267 `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)` 

3268 while `channels_first` corresponds to inputs with shape 

3269 `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`. 

3270 It defaults to the `image_data_format` value found in your 

3271 Keras config file at `~/.keras/keras.json`. 

3272 If you never set it, then it will be "channels_last". 

3273 

3274 Input shape: 

3275 5D tensor with shape: 

3276 - If `data_format` is `"channels_last"`: 

3277 `(batch_size, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop, 

3278 depth)` 

3279 - If `data_format` is `"channels_first"`: 

3280 `(batch_size, depth, first_axis_to_crop, second_axis_to_crop, 

3281 third_axis_to_crop)` 

3282 

3283 Output shape: 

3284 5D tensor with shape: 

3285 - If `data_format` is `"channels_last"`: 

3286 `(batch_size, first_cropped_axis, second_cropped_axis, third_cropped_axis, 

3287 depth)` 

3288 - If `data_format` is `"channels_first"`: 

3289 `(batch_size, depth, first_cropped_axis, second_cropped_axis, 

3290 third_cropped_axis)` 

3291 """ 

3292 

3293 def __init__(self, 

3294 cropping=((1, 1), (1, 1), (1, 1)), 

3295 data_format=None, 

3296 **kwargs): 

3297 super(Cropping3D, self).__init__(**kwargs) 

3298 self.data_format = conv_utils.normalize_data_format(data_format) 

3299 if isinstance(cropping, int): 

3300 self.cropping = ((cropping, cropping), (cropping, cropping), (cropping, 

3301 cropping)) 

3302 elif hasattr(cropping, '__len__'): 

3303 if len(cropping) != 3: 

3304 raise ValueError('`cropping` should have 3 elements. ' 

3305 'Found: ' + str(cropping)) 

3306 dim1_cropping = conv_utils.normalize_tuple(cropping[0], 2, 

3307 '1st entry of cropping') 

3308 dim2_cropping = conv_utils.normalize_tuple(cropping[1], 2, 

3309 '2nd entry of cropping') 

3310 dim3_cropping = conv_utils.normalize_tuple(cropping[2], 2, 

3311 '3rd entry of cropping') 

3312 self.cropping = (dim1_cropping, dim2_cropping, dim3_cropping) 

3313 else: 

3314 raise ValueError( 

3315 '`cropping` should be either an int, ' 

3316 'a tuple of 3 ints ' 

3317 '(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop), ' 

3318 'or a tuple of 3 tuples of 2 ints ' 

3319 '((left_dim1_crop, right_dim1_crop),' 

3320 ' (left_dim2_crop, right_dim2_crop),' 

3321 ' (left_dim3_crop, right_dim2_crop)). ' 

3322 'Found: ' + str(cropping)) 

3323 self.input_spec = InputSpec(ndim=5) 

3324 

3325 def compute_output_shape(self, input_shape): 

3326 input_shape = tensor_shape.TensorShape(input_shape).as_list() 

3327 # pylint: disable=invalid-unary-operand-type 

3328 if self.data_format == 'channels_first': 

3329 if input_shape[2] is not None: 

3330 dim1 = input_shape[2] - self.cropping[0][0] - self.cropping[0][1] 

3331 else: 

3332 dim1 = None 

3333 if input_shape[3] is not None: 

3334 dim2 = input_shape[3] - self.cropping[1][0] - self.cropping[1][1] 

3335 else: 

3336 dim2 = None 

3337 if input_shape[4] is not None: 

3338 dim3 = input_shape[4] - self.cropping[2][0] - self.cropping[2][1] 

3339 else: 

3340 dim3 = None 

3341 return tensor_shape.TensorShape( 

3342 [input_shape[0], input_shape[1], dim1, dim2, dim3]) 

3343 elif self.data_format == 'channels_last': 

3344 if input_shape[1] is not None: 

3345 dim1 = input_shape[1] - self.cropping[0][0] - self.cropping[0][1] 

3346 else: 

3347 dim1 = None 

3348 if input_shape[2] is not None: 

3349 dim2 = input_shape[2] - self.cropping[1][0] - self.cropping[1][1] 

3350 else: 

3351 dim2 = None 

3352 if input_shape[3] is not None: 

3353 dim3 = input_shape[3] - self.cropping[2][0] - self.cropping[2][1] 

3354 else: 

3355 dim3 = None 

3356 return tensor_shape.TensorShape( 

3357 [input_shape[0], dim1, dim2, dim3, input_shape[4]]) 

3358 # pylint: enable=invalid-unary-operand-type 

3359 

3360 def call(self, inputs): 

3361 # pylint: disable=invalid-unary-operand-type 

3362 if self.data_format == 'channels_first': 

3363 if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0: 

3364 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:, 

3365 self.cropping[2][0]:] 

3366 elif self.cropping[0][1] == self.cropping[1][1] == 0: 

3367 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:, 

3368 self.cropping[2][0]:-self.cropping[2][1]] 

3369 elif self.cropping[1][1] == self.cropping[2][1] == 0: 

3370 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], 

3371 self.cropping[1][0]:, self.cropping[2][0]:] 

3372 elif self.cropping[0][1] == self.cropping[2][1] == 0: 

3373 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]: 

3374 -self.cropping[1][1], self.cropping[2][0]:] 

3375 elif self.cropping[0][1] == 0: 

3376 return inputs[:, :, self.cropping[0][0]:, self.cropping[1][ 

3377 0]:-self.cropping[1][1], self.cropping[2][0]:-self.cropping[2][1]] 

3378 elif self.cropping[1][1] == 0: 

3379 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self. 

3380 cropping[1][0]:, self.cropping[2][0]:-self.cropping[2][1]] 

3381 elif self.cropping[2][1] == 0: 

3382 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self. 

3383 cropping[1][0]:-self.cropping[1][1], self.cropping[2][0]:] 

3384 return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], 

3385 self.cropping[1][0]:-self.cropping[1][1], self.cropping[2][ 

3386 0]:-self.cropping[2][1]] 

3387 else: 

3388 if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0: 

3389 return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, 

3390 self.cropping[2][0]:, :] 

3391 elif self.cropping[0][1] == self.cropping[1][1] == 0: 

3392 return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, 

3393 self.cropping[2][0]:-self.cropping[2][1], :] 

3394 elif self.cropping[1][1] == self.cropping[2][1] == 0: 

3395 return inputs[:, self.cropping[0][0]:-self.cropping[0][1], 

3396 self.cropping[1][0]:, self.cropping[2][0]:, :] 

3397 elif self.cropping[0][1] == self.cropping[2][1] == 0: 

3398 return inputs[:, self.cropping[0][0]:, self.cropping[1][0]: 

3399 -self.cropping[1][1], self.cropping[2][0]:, :] 

3400 elif self.cropping[0][1] == 0: 

3401 return inputs[:, self.cropping[0][0]:, self.cropping[1][ 

3402 0]:-self.cropping[1][1], self.cropping[2][0]: 

3403 -self.cropping[2][1], :] 

3404 elif self.cropping[1][1] == 0: 

3405 return inputs[:, self.cropping[0][ 

3406 0]:-self.cropping[0][1], self.cropping[1][0]:, self.cropping[2][0]: 

3407 -self.cropping[2][1], :] 

3408 elif self.cropping[2][1] == 0: 

3409 return inputs[:, self.cropping[0][0]:-self.cropping[0][1], 

3410 self.cropping[1][0]:-self.cropping[1][1], self.cropping[ 

3411 2][0]:, :] 

3412 return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[ 

3413 1][0]:-self.cropping[1][1], self.cropping[2][0]: # pylint: disable=invalid-unary-operand-type 

3414 -self.cropping[2][1], :] # pylint: disable=invalid-unary-operand-type 

3415 # pylint: enable=invalid-unary-operand-type 

3416 

3417 def get_config(self): 

3418 config = {'cropping': self.cropping, 'data_format': self.data_format} 

3419 base_config = super(Cropping3D, self).get_config() 

3420 return dict(list(base_config.items()) + list(config.items())) 

3421 

3422 

3423# Aliases 

3424 

3425Convolution1D = Conv1D 

3426Convolution2D = Conv2D 

3427Convolution3D = Conv3D 

3428SeparableConvolution1D = SeparableConv1D 

3429SeparableConvolution2D = SeparableConv2D 

3430Convolution2DTranspose = Conv2DTranspose 

3431Convolution3DTranspose = Conv3DTranspose 

3432Deconvolution2D = Deconv2D = Conv2DTranspose 

3433Deconvolution3D = Deconv3D = Conv3DTranspose