Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/keras/src/layers/convolutional/base_separable_conv.py: 33%
39 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 abstract base layer for separable nD convolution."""
18import tensorflow.compat.v2 as tf
20from keras.src import activations
21from keras.src import constraints
22from keras.src import initializers
23from keras.src import regularizers
24from keras.src.engine.input_spec import InputSpec
25from keras.src.layers.convolutional.base_conv import Conv
28class SeparableConv(Conv):
29 """Abstract base layer for separable nD convolution.
31 This layer performs a depthwise convolution that acts separately on
32 channels, followed by a pointwise convolution that mixes channels.
33 If `use_bias` is True and a bias initializer is provided,
34 it adds a bias vector to the output.
35 It then optionally applies an activation function to produce the final
36 output.
38 Args:
39 rank: An integer, the rank of the convolution, e.g. "2" for 2D
40 convolution.
41 filters: Integer, the dimensionality of the output space (i.e. the number
42 of filters in the convolution).
43 kernel_size: A tuple or list of integers specifying the spatial
44 dimensions of the filters. Can be a single integer to specify the same
45 value for all spatial dimensions.
46 strides: A tuple or list of integers specifying the strides
47 of the convolution. Can be a single integer to specify the same value
48 for all spatial dimensions.
49 Specifying any `stride` value != 1 is incompatible with specifying
50 any `dilation_rate` value != 1.
51 padding: One of `"valid"` or `"same"` (case-insensitive).
52 `"valid"` means no padding. `"same"` results in padding with zeros
53 evenly to the left/right or up/down of the input such that output has
54 the same height/width dimension as the input.
55 data_format: A string, one of `channels_last` (default) or
56 `channels_first`. The ordering of the dimensions in the inputs.
57 `channels_last` corresponds to inputs with shape
58 `(batch_size, ..., channels)` while `channels_first` corresponds to
59 inputs with shape `(batch_size, channels, ...)`.
60 dilation_rate: An integer or tuple/list of 2 integers, specifying
61 the dilation rate to use for dilated convolution.
62 Can be a single integer to specify the same value for
63 all spatial dimensions.
64 Currently, specifying any `dilation_rate` value != 1 is
65 incompatible with specifying any stride value != 1.
66 depth_multiplier: The number of depthwise convolution output channels for
67 each input channel. The total number of depthwise convolution output
68 channels will be equal to `num_filters_in * depth_multiplier`.
69 activation: Activation function to use.
70 If you don't specify anything, no activation is applied
71 (see `keras.activations`).
72 use_bias: Boolean, whether the layer uses a bias.
73 depthwise_initializer: An initializer for the depthwise convolution kernel
74 (see `keras.initializers`). If None, then the default initializer
75 ('glorot_uniform') will be used.
76 pointwise_initializer: An initializer for the pointwise convolution kernel
77 (see `keras.initializers`). If None, then the default initializer
78 ('glorot_uniform') will be used.
79 bias_initializer: An initializer for the bias vector. If None, the default
80 initializer ('zeros') will be used (see `keras.initializers`).
81 depthwise_regularizer: Optional regularizer for the depthwise
82 convolution kernel.
83 pointwise_regularizer: Optional regularizer for the pointwise
84 convolution kernel.
85 bias_regularizer: Optional regularizer for the bias vector.
86 activity_regularizer: Optional regularizer function for the output.
87 depthwise_constraint: Optional projection function to be applied to the
88 depthwise kernel after being updated by an `Optimizer` (e.g. used for
89 norm constraints or value constraints for layer weights). The function
90 must take as input the unprojected variable and must return the
91 projected variable (which must have the same shape). Constraints are
92 not safe to use when doing asynchronous distributed training.
93 pointwise_constraint: Optional projection function to be applied to the
94 pointwise kernel after being updated by an `Optimizer`.
95 bias_constraint: Optional projection function to be applied to the
96 bias after being updated by an `Optimizer`.
97 trainable: Boolean, if `True` the weights of this layer will be marked as
98 trainable (and listed in `layer.trainable_weights`).
99 """
101 def __init__(
102 self,
103 rank,
104 filters,
105 kernel_size,
106 strides=1,
107 padding="valid",
108 data_format=None,
109 dilation_rate=1,
110 depth_multiplier=1,
111 activation=None,
112 use_bias=True,
113 depthwise_initializer="glorot_uniform",
114 pointwise_initializer="glorot_uniform",
115 bias_initializer="zeros",
116 depthwise_regularizer=None,
117 pointwise_regularizer=None,
118 bias_regularizer=None,
119 activity_regularizer=None,
120 depthwise_constraint=None,
121 pointwise_constraint=None,
122 bias_constraint=None,
123 trainable=True,
124 name=None,
125 **kwargs,
126 ):
127 super().__init__(
128 rank=rank,
129 filters=filters,
130 kernel_size=kernel_size,
131 strides=strides,
132 padding=padding,
133 data_format=data_format,
134 dilation_rate=dilation_rate,
135 activation=activations.get(activation),
136 use_bias=use_bias,
137 bias_initializer=initializers.get(bias_initializer),
138 bias_regularizer=regularizers.get(bias_regularizer),
139 activity_regularizer=regularizers.get(activity_regularizer),
140 bias_constraint=bias_constraint,
141 trainable=trainable,
142 name=name,
143 **kwargs,
144 )
145 self.depth_multiplier = depth_multiplier
146 self.depthwise_initializer = initializers.get(depthwise_initializer)
147 self.pointwise_initializer = initializers.get(pointwise_initializer)
148 self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
149 self.pointwise_regularizer = regularizers.get(pointwise_regularizer)
150 self.depthwise_constraint = constraints.get(depthwise_constraint)
151 self.pointwise_constraint = constraints.get(pointwise_constraint)
153 def build(self, input_shape):
154 input_shape = tf.TensorShape(input_shape)
155 channel_axis = self._get_channel_axis()
156 if input_shape.dims[channel_axis].value is None:
157 raise ValueError(
158 "The channel dimension of the inputs should be defined. "
159 f"The input_shape received is {input_shape}, "
160 f"where axis {channel_axis} (0-based) "
161 "is the channel dimension, which found to be `None`."
162 )
163 input_dim = int(input_shape[channel_axis])
164 self.input_spec = InputSpec(
165 ndim=self.rank + 2, axes={channel_axis: input_dim}
166 )
167 depthwise_kernel_shape = self.kernel_size + (
168 input_dim,
169 self.depth_multiplier,
170 )
171 pointwise_kernel_shape = (1,) * self.rank + (
172 self.depth_multiplier * input_dim,
173 self.filters,
174 )
176 self.depthwise_kernel = self.add_weight(
177 name="depthwise_kernel",
178 shape=depthwise_kernel_shape,
179 initializer=self.depthwise_initializer,
180 regularizer=self.depthwise_regularizer,
181 constraint=self.depthwise_constraint,
182 trainable=True,
183 dtype=self.dtype,
184 )
185 self.pointwise_kernel = self.add_weight(
186 name="pointwise_kernel",
187 shape=pointwise_kernel_shape,
188 initializer=self.pointwise_initializer,
189 regularizer=self.pointwise_regularizer,
190 constraint=self.pointwise_constraint,
191 trainable=True,
192 dtype=self.dtype,
193 )
194 if self.use_bias:
195 self.bias = self.add_weight(
196 name="bias",
197 shape=(self.filters,),
198 initializer=self.bias_initializer,
199 regularizer=self.bias_regularizer,
200 constraint=self.bias_constraint,
201 trainable=True,
202 dtype=self.dtype,
203 )
204 else:
205 self.bias = None
206 self.built = True
208 def call(self, inputs):
209 raise NotImplementedError
211 def get_config(self):
212 config = {
213 "filters": self.filters,
214 "kernel_size": self.kernel_size,
215 "strides": self.strides,
216 "padding": self.padding,
217 "data_format": self.data_format,
218 "depth_multiplier": self.depth_multiplier,
219 "dilation_rate": self.dilation_rate,
220 "activation": activations.serialize(self.activation),
221 "use_bias": self.use_bias,
222 "depthwise_initializer": initializers.serialize(
223 self.depthwise_initializer
224 ),
225 "pointwise_initializer": initializers.serialize(
226 self.pointwise_initializer
227 ),
228 "bias_initializer": initializers.serialize(self.bias_initializer),
229 "depthwise_regularizer": regularizers.serialize(
230 self.depthwise_regularizer
231 ),
232 "pointwise_regularizer": regularizers.serialize(
233 self.pointwise_regularizer
234 ),
235 "bias_regularizer": regularizers.serialize(self.bias_regularizer),
236 "activity_regularizer": regularizers.serialize(
237 self.activity_regularizer
238 ),
239 "depthwise_constraint": constraints.serialize(
240 self.depthwise_constraint
241 ),
242 "pointwise_constraint": constraints.serialize(
243 self.pointwise_constraint
244 ),
245 "bias_constraint": constraints.serialize(self.bias_constraint),
246 }
247 base_config = super().get_config()
248 return dict(list(base_config.items()) + list(config.items()))