Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/keras/src/layers/convolutional/depthwise_conv1d.py: 31%

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 depthwise 1D convolution.""" 

16 

17 

18import tensorflow.compat.v2 as tf 

19 

20from keras.src.layers.convolutional.base_depthwise_conv import DepthwiseConv 

21from keras.src.utils import conv_utils 

22from keras.src.utils import tf_utils 

23 

24# isort: off 

25from tensorflow.python.util.tf_export import keras_export 

26 

27 

28@keras_export("keras.layers.DepthwiseConv1D") 

29class DepthwiseConv1D(DepthwiseConv): 

30 """Depthwise 1D convolution. 

31 

32 Depthwise convolution is a type of convolution in which each input channel 

33 is convolved with a different kernel (called a depthwise kernel). You can 

34 understand depthwise convolution as the first step in a depthwise separable 

35 convolution. 

36 

37 It is implemented via the following steps: 

38 

39 - Split the input into individual channels. 

40 - Convolve each channel with an individual depthwise kernel with 

41 `depth_multiplier` output channels. 

42 - Concatenate the convolved outputs along the channels axis. 

43 

44 Unlike a regular 1D convolution, depthwise convolution does not mix 

45 information across different input channels. 

46 

47 The `depth_multiplier` argument determines how many filter are applied to 

48 one input channel. As such, it controls the amount of output channels that 

49 are generated per input channel in the depthwise step. 

50 

51 Args: 

52 kernel_size: An integer, specifying the height and width of the 1D 

53 convolution window. Can be a single integer to specify the same value 

54 for all spatial dimensions. 

55 strides: An integer, specifying the strides of the convolution along the 

56 height and width. Can be a single integer to specify the same value for 

57 all spatial dimensions. Specifying any stride value != 1 is incompatible 

58 with specifying any `dilation_rate` value != 1. 

59 padding: one of `'valid'` or `'same'` (case-insensitive). `"valid"` means 

60 no padding. `"same"` results in padding with zeros evenly to the 

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

62 height/width dimension as the input. 

63 depth_multiplier: The number of depthwise convolution output channels for 

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

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

66 data_format: A string, one of `channels_last` (default) or 

67 `channels_first`. The ordering of the dimensions in the inputs. 

68 `channels_last` corresponds to inputs with shape `(batch_size, height, 

69 width, channels)` while `channels_first` corresponds to inputs with 

70 shape `(batch_size, channels, height, width)`. When unspecified, uses 

71 `image_data_format` value found in your Keras config file at 

72 `~/.keras/keras.json` (if exists) else 'channels_last'. 

73 Defaults to 'channels_last'. 

74 dilation_rate: A single integer, specifying the dilation rate to use for 

75 dilated convolution. Currently, specifying any `dilation_rate` 

76 value != 1 is incompatible with specifying any stride value != 1. 

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

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

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

80 depthwise_initializer: Initializer for the depthwise kernel matrix (see 

81 `keras.initializers`). If None, the default initializer 

82 ('glorot_uniform') will be used. 

83 bias_initializer: Initializer for the bias vector (see 

84 `keras.initializers`). If None, the default initializer ('zeros') will 

85 be used. 

86 depthwise_regularizer: Regularizer function applied to the depthwise 

87 kernel matrix (see `keras.regularizers`). 

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

89 `keras.regularizers`). 

90 activity_regularizer: Regularizer function applied to the output of the 

91 layer (its 'activation') (see `keras.regularizers`). 

92 depthwise_constraint: Constraint function applied to the depthwise kernel 

93 matrix (see `keras.constraints`). 

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

95 `keras.constraints`). 

96 

97 Input shape: 

98 3D tensor with shape: `[batch_size, channels, input_dim]` if 

99 data_format='channels_first' 

100 or 3D tensor with shape: `[batch_size, input_dim, channels]` if 

101 data_format='channels_last'. 

102 

103 Output shape: 

104 3D tensor with shape: 

105 `[batch_size, channels * depth_multiplier, new_dims]` 

106 if `data_format='channels_first'` 

107 or 3D tensor with shape: `[batch_size, 

108 new_dims, channels * depth_multiplier]` if 

109 `data_format='channels_last'`. `new_dims` values might have 

110 changed due to padding. 

111 

112 Returns: 

113 A tensor of rank 3 representing 

114 `activation(depthwiseconv1d(inputs, kernel) + bias)`. 

115 

116 Raises: 

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

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

119 """ 

120 

121 def __init__( 

122 self, 

123 kernel_size, 

124 strides=1, 

125 padding="valid", 

126 depth_multiplier=1, 

127 data_format=None, 

128 dilation_rate=1, 

129 activation=None, 

130 use_bias=True, 

131 depthwise_initializer="glorot_uniform", 

132 bias_initializer="zeros", 

133 depthwise_regularizer=None, 

134 bias_regularizer=None, 

135 activity_regularizer=None, 

136 depthwise_constraint=None, 

137 bias_constraint=None, 

138 **kwargs 

139 ): 

140 super().__init__( 

141 1, 

142 kernel_size=kernel_size, 

143 strides=strides, 

144 padding=padding, 

145 depth_multiplier=depth_multiplier, 

146 data_format=data_format, 

147 dilation_rate=dilation_rate, 

148 activation=activation, 

149 use_bias=use_bias, 

150 depthwise_initializer=depthwise_initializer, 

151 bias_initializer=bias_initializer, 

152 depthwise_regularizer=depthwise_regularizer, 

153 bias_regularizer=bias_regularizer, 

154 activity_regularizer=activity_regularizer, 

155 depthwise_constraint=depthwise_constraint, 

156 bias_constraint=bias_constraint, 

157 **kwargs 

158 ) 

159 

160 def call(self, inputs): 

161 if self.data_format == "channels_last": 

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

163 spatial_start_dim = 1 

164 else: 

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

166 spatial_start_dim = 2 

167 inputs = tf.expand_dims(inputs, spatial_start_dim) 

168 depthwise_kernel = tf.expand_dims(self.depthwise_kernel, axis=0) 

169 dilation_rate = (1,) + self.dilation_rate 

170 

171 outputs = tf.nn.depthwise_conv2d( 

172 inputs, 

173 depthwise_kernel, 

174 strides=strides, 

175 padding=self.padding.upper(), 

176 dilations=dilation_rate, 

177 data_format=conv_utils.convert_data_format( 

178 self.data_format, ndim=4 

179 ), 

180 ) 

181 

182 if self.use_bias: 

183 outputs = tf.nn.bias_add( 

184 outputs, 

185 self.bias, 

186 data_format=conv_utils.convert_data_format( 

187 self.data_format, ndim=4 

188 ), 

189 ) 

190 

191 outputs = tf.squeeze(outputs, [spatial_start_dim]) 

192 

193 if self.activation is not None: 

194 return self.activation(outputs) 

195 

196 return outputs 

197 

198 @tf_utils.shape_type_conversion 

199 def compute_output_shape(self, input_shape): 

200 if self.data_format == "channels_first": 

201 input_dim = input_shape[2] 

202 out_filters = input_shape[1] * self.depth_multiplier 

203 elif self.data_format == "channels_last": 

204 input_dim = input_shape[1] 

205 out_filters = input_shape[2] * self.depth_multiplier 

206 

207 input_dim = conv_utils.conv_output_length( 

208 input_dim, 

209 self.kernel_size[0], 

210 self.padding, 

211 self.strides[0], 

212 self.dilation_rate[0], 

213 ) 

214 if self.data_format == "channels_first": 

215 return (input_shape[0], out_filters, input_dim) 

216 elif self.data_format == "channels_last": 

217 return (input_shape[0], input_dim, out_filters) 

218