Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/keras/src/layers/convolutional/depthwise_conv2d.py: 36%
33 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Keras depthwise 2D convolution."""
18from keras.src import backend
19from keras.src.layers.convolutional.base_depthwise_conv import DepthwiseConv
20from keras.src.utils import conv_utils
21from keras.src.utils import tf_utils
23# isort: off
24from tensorflow.python.util.tf_export import keras_export
27@keras_export("keras.layers.DepthwiseConv2D")
28class DepthwiseConv2D(DepthwiseConv):
29 """Depthwise 2D convolution.
31 Depthwise convolution is a type of convolution in which each input channel
32 is convolved with a different kernel (called a depthwise kernel). You can
33 understand depthwise convolution as the first step in a depthwise separable
34 convolution.
36 It is implemented via the following steps:
38 - Split the input into individual channels.
39 - Convolve each channel with an individual depthwise kernel with
40 `depth_multiplier` output channels.
41 - Concatenate the convolved outputs along the channels axis.
43 Unlike a regular 2D convolution, depthwise convolution does not mix
44 information across different input channels.
46 The `depth_multiplier` argument determines how many filter are applied to
47 one input channel. As such, it controls the amount of output channels that
48 are generated per input channel in the depthwise step.
50 Args:
51 kernel_size: An integer or tuple/list of 2 integers, specifying the height
52 and width of the 2D convolution window. Can be a single integer to
53 specify the same value for all spatial dimensions.
54 strides: An integer or tuple/list of 2 integers, specifying the strides of
55 the convolution along the height and width. Can be a single integer to
56 specify the same value for all spatial dimensions. Current
57 implementation only supports equal length strides in row and
58 column dimensions. Specifying any stride value != 1 is incompatible
59 with specifying any `dilation_rate` value !=1.
60 padding: one of `'valid'` or `'same'` (case-insensitive). `"valid"` means
61 no padding. `"same"` results in padding with zeros evenly to the
62 left/right or up/down of the input such that output has the same
63 height/width dimension as the input.
64 depth_multiplier: The number of depthwise convolution output channels for
65 each input channel. The total number of depthwise convolution output
66 channels will be equal to `filters_in * depth_multiplier`.
67 data_format: A string, one of `channels_last` (default) or
68 `channels_first`. The ordering of the dimensions in the inputs.
69 `channels_last` corresponds to inputs with shape `(batch_size, height,
70 width, channels)` while `channels_first` corresponds to inputs with
71 shape `(batch_size, channels, height, width)`. When unspecified, uses
72 `image_data_format` value found in your Keras config file at
73 `~/.keras/keras.json` (if exists) else 'channels_last'.
74 Defaults to 'channels_last'.
75 dilation_rate: An integer or tuple/list of 2 integers, specifying the
76 dilation rate to use for dilated convolution. Currently, specifying any
77 `dilation_rate` value != 1 is incompatible with specifying any `strides`
78 value != 1.
79 activation: Activation function to use. If you don't specify anything, no
80 activation is applied (see `keras.activations`).
81 use_bias: Boolean, whether the layer uses a bias vector.
82 depthwise_initializer: Initializer for the depthwise kernel matrix (see
83 `keras.initializers`). If None, the default initializer
84 ('glorot_uniform') will be used.
85 bias_initializer: Initializer for the bias vector (see
86 `keras.initializers`). If None, the default initializer ('zeros') will
87 be used.
88 depthwise_regularizer: Regularizer function applied to the depthwise
89 kernel matrix (see `keras.regularizers`).
90 bias_regularizer: Regularizer function applied to the bias vector (see
91 `keras.regularizers`).
92 activity_regularizer: Regularizer function applied to the output of the
93 layer (its 'activation') (see `keras.regularizers`).
94 depthwise_constraint: Constraint function applied to the depthwise kernel
95 matrix (see `keras.constraints`).
96 bias_constraint: Constraint function applied to the bias vector (see
97 `keras.constraints`).
99 Input shape:
100 4D tensor with shape: `[batch_size, channels, rows, cols]` if
101 data_format='channels_first'
102 or 4D tensor with shape: `[batch_size, rows, cols, channels]` if
103 data_format='channels_last'.
105 Output shape:
106 4D tensor with shape: `[batch_size, channels * depth_multiplier, new_rows,
107 new_cols]` if `data_format='channels_first'`
108 or 4D tensor with shape: `[batch_size,
109 new_rows, new_cols, channels * depth_multiplier]` if
110 `data_format='channels_last'`. `rows` and `cols` values might have
111 changed due to padding.
113 Returns:
114 A tensor of rank 4 representing
115 `activation(depthwiseconv2d(inputs, kernel) + bias)`.
117 Raises:
118 ValueError: if `padding` is "causal".
119 ValueError: when both `strides` > 1 and `dilation_rate` > 1.
120 """
122 def __init__(
123 self,
124 kernel_size,
125 strides=(1, 1),
126 padding="valid",
127 depth_multiplier=1,
128 data_format=None,
129 dilation_rate=(1, 1),
130 activation=None,
131 use_bias=True,
132 depthwise_initializer="glorot_uniform",
133 bias_initializer="zeros",
134 depthwise_regularizer=None,
135 bias_regularizer=None,
136 activity_regularizer=None,
137 depthwise_constraint=None,
138 bias_constraint=None,
139 **kwargs
140 ):
141 super().__init__(
142 2,
143 kernel_size=kernel_size,
144 strides=strides,
145 padding=padding,
146 depth_multiplier=depth_multiplier,
147 data_format=data_format,
148 dilation_rate=dilation_rate,
149 activation=activation,
150 use_bias=use_bias,
151 depthwise_initializer=depthwise_initializer,
152 bias_initializer=bias_initializer,
153 depthwise_regularizer=depthwise_regularizer,
154 bias_regularizer=bias_regularizer,
155 activity_regularizer=activity_regularizer,
156 depthwise_constraint=depthwise_constraint,
157 bias_constraint=bias_constraint,
158 **kwargs
159 )
161 def call(self, inputs):
162 outputs = backend.depthwise_conv2d(
163 inputs,
164 self.depthwise_kernel,
165 strides=self.strides,
166 padding=self.padding,
167 dilation_rate=self.dilation_rate,
168 data_format=self.data_format,
169 )
171 if self.use_bias:
172 outputs = backend.bias_add(
173 outputs, self.bias, data_format=self.data_format
174 )
176 if self.activation is not None:
177 return self.activation(outputs)
179 return outputs
181 @tf_utils.shape_type_conversion
182 def compute_output_shape(self, input_shape):
183 if self.data_format == "channels_first":
184 rows = input_shape[2]
185 cols = input_shape[3]
186 out_filters = input_shape[1] * self.depth_multiplier
187 elif self.data_format == "channels_last":
188 rows = input_shape[1]
189 cols = input_shape[2]
190 out_filters = input_shape[3] * self.depth_multiplier
192 rows = conv_utils.conv_output_length(
193 rows,
194 self.kernel_size[0],
195 self.padding,
196 self.strides[0],
197 self.dilation_rate[0],
198 )
199 cols = conv_utils.conv_output_length(
200 cols,
201 self.kernel_size[1],
202 self.padding,
203 self.strides[1],
204 self.dilation_rate[1],
205 )
206 if self.data_format == "channels_first":
207 return (input_shape[0], out_filters, rows, cols)
208 elif self.data_format == "channels_last":
209 return (input_shape[0], rows, cols, out_filters)