@@ -286,6 +286,43 @@ final class LayerTests: XCTestCase {
286
286
XCTAssertEqual ( output, expected)
287
287
}
288
288
289
+ func testSeparableConv2DGradient( ) {
290
+ let depthwiseFilter = Tensor ( shape: [ 2 , 1 , 2 , 2 ] , scalars: ( 0 ..< 8 ) . map ( Float . init) )
291
+ let pointwiseFilter = Tensor ( shape: [ 1 , 1 , 4 , 1 ] , scalars: ( 0 ..< 4 ) . map ( Float . init) )
292
+ let bias = Tensor < Float > ( [ 1 , 1 ] )
293
+ let layer = SeparableConv2D < Float > ( depthwiseFilter: depthwiseFilter,
294
+ pointwiseFilter: pointwiseFilter,
295
+ bias: bias,
296
+ activation: identity,
297
+ strides: ( 1 , 1 ) ,
298
+ padding: . same)
299
+ let input = Tensor ( shape: [ 2 , 1 , 2 , 2 ] , scalars: ( 0 ..< 8 ) . map ( Float . init) )
300
+ let grads = gradient ( at: input, layer) { $1 ( $0) . sum ( ) }
301
+ // The expected value of the gradient was computed using the following Python code:
302
+ // ```
303
+ // import tensorflow as tf
304
+ // x = tf.reshape(tf.range(8, dtype=tf.float32), [2, 1, 2, 2])
305
+ // depthwiseFilter = tf.reshape(tf.range(8, dtype=tf.float32), [2, 1, 2, 2])
306
+ // pointwiseFilter = tf.reshape(tf.range(4, dtype=tf.float32), [1, 1, 4, 1])
307
+ // bias = tf.ones([2])
308
+ // with tf.GradientTape() as tape:
309
+ // tape.watch([x, depthwiseFilter, pointwiseFilter, bias])
310
+ // y = tf.math.reduce_sum(tf.nn.separable_conv2D(input,
311
+ // depthwiseFilter,
312
+ // pointwiseFilter
313
+ // strides=[1, 1, 1, 1],
314
+ // padding="SAME") + bias)
315
+ // print(tape.gradient(y, [x, depthwiseFilter, pointwiseFilter, bias])
316
+ // ```
317
+ XCTAssertEqual ( grads. 0 ,
318
+ [ [ [ [ 2.0 , 26.0 ] , [ 2.0 , 26.0 ] ] ] ,
319
+ [ [ [ 2.0 , 26.0 ] , [ 2.0 , 26.0 ] ] ] ] )
320
+ XCTAssertEqual ( grads. 1 . depthwiseFilter,
321
+ [ [ [ [ 0.0 , 24.0 ] , [ 64.0 , 96.0 ] ] ] ,
322
+ [ [ [ 0.0 , 0.0 ] , [ 0.0 , 0.0 ] ] ] ] )
323
+ XCTAssertEqual ( grads. 1 . bias, [ 4.0 , 4.0 ] )
324
+ }
325
+
289
326
func testZeroPadding1D( ) {
290
327
let input = Tensor < Float > ( shape: [ 1 , 3 , 1 ] , scalars: [ 0.0 , 1.0 , 2.0 ] )
291
328
let layer = ZeroPadding1D < Float > ( padding: 2 )
@@ -1241,6 +1278,7 @@ final class LayerTests: XCTestCase {
1241
1278
( " testDepthwiseConv2DGradient " , testDepthwiseConv2DGradient) ,
1242
1279
( " testSeparableConv1D " , testSeparableConv1D) ,
1243
1280
( " testSeparableConv2D " , testSeparableConv2D) ,
1281
+ ( " testSeparableConv2DGradient " , testSeparableConv2DGradient) ,
1244
1282
( " testZeroPadding1D " , testZeroPadding1D) ,
1245
1283
( " testZeroPadding1DGradient " , testZeroPadding1DGradient) ,
1246
1284
( " testZeroPadding2D " , testZeroPadding2D) ,
0 commit comments