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

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.""" 

16 

17 

18import tensorflow.compat.v2 as tf 

19 

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 

26 

27 

28class SeparableConv(Conv): 

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

30 

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. 

37 

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 """ 

100 

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) 

152 

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 ) 

175 

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 

207 

208 def call(self, inputs): 

209 raise NotImplementedError 

210 

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())) 

249