@@ -284,77 +284,187 @@ final class TensorAutoDiffTests: XCTestCase {
284
284
XCTAssertEqual ( varianceGradAlongAxes ( input) , expected)
285
285
}
286
286
287
- func testMin( ) {
288
- // The expected gradient values were computed using the following TensorFlow 2.0 Beta1
289
- // Python code with respective `a` and `b` tensors:
287
+ func testMax( ) {
288
+ // Expected gradient values were computed using the following TensorFlow Python code:
290
289
// ```
290
+ // import tensorflow as tf
291
291
// with tf.GradientTape() as t:
292
292
// t.watch([a, b])
293
- // y = tf.math. reduce_sum(tf.minimum (a, b))
293
+ // y = tf.reduce_sum(tf.maximum (a, b))
294
294
// print(t.gradient(y, [a, b]))
295
295
// ```
296
296
do {
297
297
let a = Tensor < Float > ( [ 4 , 5 , 3 ] )
298
298
let b = Tensor < Float > ( [ 4 , 2 , 6 ] )
299
- let computedGradient1 = gradient ( at: a, b) { a, b in min ( a, b) . sum ( ) }
300
- let expectedGradient1 : ( Tensor < Float > , Tensor < Float > ) = (
301
- [ 1.0 , 0.0 , 1.0 ] , [ 0.0 , 1.0 , 0.0 ] )
299
+ let computedGradient1 = gradient ( at: a, b) { a, b in max ( a, b) . sum ( ) }
300
+ let expectedGradient1 : ( Tensor < Float > , Tensor < Float > ) = ( [ 1 , 1 , 0 ] , [ 0 , 0 , 1 ] )
302
301
XCTAssertEqual ( computedGradient1. 0 , expectedGradient1. 0 )
303
302
XCTAssertEqual ( computedGradient1. 1 , expectedGradient1. 1 )
304
303
305
- let computedGradient2 = gradient ( at: a, b) { a, b in min ( b, a) . sum ( ) }
306
- let expectedGradient2 : ( Tensor < Float > , Tensor < Float > ) = (
307
- [ 0.0 , 0.0 , 1.0 ] , [ 1.0 , 1.0 , 0.0 ] )
304
+ let computedGradient2 = gradient ( at: a, b) { a, b in max ( b, a) . sum ( ) }
305
+ let expectedGradient2 : ( Tensor < Float > , Tensor < Float > ) = ( [ 0 , 1 , 0 ] , [ 1 , 0 , 1 ] )
308
306
XCTAssertEqual ( computedGradient2. 0 , expectedGradient2. 0 )
309
307
XCTAssertEqual ( computedGradient2. 1 , expectedGradient2. 1 )
310
308
}
311
-
312
309
do {
313
- let a = Tensor < Float > ( [ [ 3.0 , - 2.0 ] , [ 0.3 , 10.0 ] ] )
314
- let b = Tensor < Float > ( [ 9.0 , - 3.0 ] )
315
- let computedGradient = gradient ( at: a, b) { a, b in min ( a, b) . sum ( ) }
316
- let expectedGradient : ( Tensor < Float > , Tensor < Float > ) = (
317
- [ [ 1.0 , 0.0 ] , [ 1.0 , 0.0 ] ] , [ 0.0 , 2.0 ] )
310
+ let a = Tensor < Float > ( [ [ 3 , - 2 ] , [ 0.3 , 10 ] ] )
311
+ let b = Tensor < Float > ( [ 9 , - 3 ] )
312
+ let computedGradient = gradient ( at: a, b) { a, b in max ( a, b) . sum ( ) }
313
+ let expectedGradient : ( Tensor < Float > , Tensor < Float > ) = ( [ [ 0 , 1 ] , [ 0 , 1 ] ] , [ 2 , 0 ] )
318
314
XCTAssertEqual ( computedGradient. 0 , expectedGradient. 0 )
319
315
XCTAssertEqual ( computedGradient. 1 , expectedGradient. 1 )
320
316
}
321
317
}
322
318
323
- func testMax( ) {
324
- // The expected gradient values were computed using the following TensorFlow 2.0 Beta1
325
- // Python code with respective `a` and `b` tensors:
319
+ func testMin( ) {
320
+ // Expected gradient values were computed using the following TensorFlow Python code:
326
321
// ```
322
+ // import tensorflow as tf
327
323
// with tf.GradientTape() as t:
328
324
// t.watch([a, b])
329
- // y = tf.math. reduce_sum(tf.maximum (a, b))
325
+ // y = tf.reduce_sum(tf.minimum (a, b))
330
326
// print(t.gradient(y, [a, b]))
331
327
// ```
332
328
do {
333
329
let a = Tensor < Float > ( [ 4 , 5 , 3 ] )
334
330
let b = Tensor < Float > ( [ 4 , 2 , 6 ] )
335
- let computedGradient1 = gradient ( at: a, b) { a, b in max ( a, b) . sum ( ) }
336
- let expectedGradient1 : ( Tensor < Float > , Tensor < Float > ) = (
337
- [ 1.0 , 1.0 , 0.0 ] , [ 0.0 , 0.0 , 1.0 ] )
331
+ let computedGradient1 = gradient ( at: a, b) { a, b in min ( a, b) . sum ( ) }
332
+ let expectedGradient1 : ( Tensor < Float > , Tensor < Float > ) = ( [ 1 , 0 , 1 ] , [ 0 , 1 , 0 ] )
338
333
XCTAssertEqual ( computedGradient1. 0 , expectedGradient1. 0 )
339
334
XCTAssertEqual ( computedGradient1. 1 , expectedGradient1. 1 )
340
335
341
- let computedGradient2 = gradient ( at: a, b) { a, b in max ( b, a) . sum ( ) }
342
- let expectedGradient2 : ( Tensor < Float > , Tensor < Float > ) = (
343
- [ 0.0 , 1.0 , 0.0 ] , [ 1.0 , 0.0 , 1.0 ] )
336
+ let computedGradient2 = gradient ( at: a, b) { a, b in min ( b, a) . sum ( ) }
337
+ let expectedGradient2 : ( Tensor < Float > , Tensor < Float > ) = ( [ 0 , 0 , 1 ] , [ 1 , 1 , 0 ] )
344
338
XCTAssertEqual ( computedGradient2. 0 , expectedGradient2. 0 )
345
339
XCTAssertEqual ( computedGradient2. 1 , expectedGradient2. 1 )
346
340
}
341
+
347
342
do {
348
- let a = Tensor < Float > ( [ [ 3.0 , - 2.0 ] , [ 0.3 , 10.0 ] ] )
349
- let b = Tensor < Float > ( [ 9.0 , - 3.0 ] )
350
- let computedGradient = gradient ( at: a, b) { a, b in max ( a, b) . sum ( ) }
351
- let expectedGradient : ( Tensor < Float > , Tensor < Float > ) = (
352
- [ [ 0.0 , 1.0 ] , [ 0.0 , 1.0 ] ] , [ 2.0 , 0.0 ] )
343
+ let a = Tensor < Float > ( [ [ 3 , - 2 ] , [ 0.3 , 10 ] ] )
344
+ let b = Tensor < Float > ( [ 9 , - 3 ] )
345
+ let computedGradient = gradient ( at: a, b) { a, b in min ( a, b) . sum ( ) }
346
+ let expectedGradient : ( Tensor < Float > , Tensor < Float > ) = ( [ [ 1 , 0 ] , [ 1 , 0 ] ] , [ 0 , 2 ] )
353
347
XCTAssertEqual ( computedGradient. 0 , expectedGradient. 0 )
354
348
XCTAssertEqual ( computedGradient. 1 , expectedGradient. 1 )
355
349
}
356
350
}
357
351
352
+ func testMaxAlongAxes( ) {
353
+ // Expected gradient values were computed using the following TensorFlow Python code:
354
+ // ```
355
+ // import tensorflow as tf
356
+ // x = tf.constant(range(6), shape=(2, 3), dtype=float)
357
+ // with tf.GradientTape() as t:
358
+ // t.watch(x)
359
+ // y = tf.reduce_sum(tf.reduce_max(x, axis=0, keepdims=True))
360
+ // print(t.gradient(y, x))
361
+ // ```
362
+ func maxAlongAxesSum( _ x: Tensor < Float > ) -> Tensor < Float > {
363
+ x. max ( alongAxes: 0 ) . sum ( )
364
+ }
365
+ do {
366
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 3 , 4 , 5 ] ]
367
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: maxAlongAxesSum)
368
+ XCTAssertEqual ( value, maxAlongAxesSum ( x) )
369
+ let expectedGradient : Tensor < Float > = [ [ 0 , 0 , 0 ] , [ 1 , 1 , 1 ] ]
370
+ XCTAssertEqual ( computedGradient, expectedGradient)
371
+ }
372
+ do {
373
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 2 , 1 , 0 ] ]
374
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: maxAlongAxesSum)
375
+ XCTAssertEqual ( value, maxAlongAxesSum ( x) )
376
+ let expectedGradient : Tensor < Float > = [ [ 0 , 0.5 , 1 ] , [ 1 , 0.5 , 0 ] ]
377
+ XCTAssertEqual ( computedGradient, expectedGradient)
378
+ }
379
+ }
380
+
381
+ func testMinAlongAxes( ) {
382
+ // Expected gradient values were computed using the following TensorFlow Python code:
383
+ // ```
384
+ // import tensorflow as tf
385
+ // x = tf.constant(range(6), shape=(2, 3), dtype=float)
386
+ // with tf.GradientTape() as t:
387
+ // t.watch(x)
388
+ // y = tf.reduce_sum(tf.reduce_min(x, axis=0, keepdims=True))
389
+ // print(t.gradient(y, x))
390
+ // ```
391
+ func minAlongAxesSum( _ x: Tensor < Float > ) -> Tensor < Float > {
392
+ x. min ( alongAxes: 0 ) . sum ( )
393
+ }
394
+ do {
395
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 3 , 4 , 5 ] ]
396
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: minAlongAxesSum)
397
+ XCTAssertEqual ( value, minAlongAxesSum ( x) )
398
+ let expectedGradient : Tensor < Float > = [ [ 1 , 1 , 1 ] , [ 0 , 0 , 0 ] ]
399
+ XCTAssertEqual ( computedGradient, expectedGradient)
400
+ }
401
+ do {
402
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 2 , 1 , 0 ] ]
403
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: minAlongAxesSum)
404
+ XCTAssertEqual ( value, minAlongAxesSum ( x) )
405
+ let expectedGradient : Tensor < Float > = [ [ 1 , 0.5 , 0 ] , [ 0 , 0.5 , 1 ] ]
406
+ XCTAssertEqual ( computedGradient, expectedGradient)
407
+ }
408
+ }
409
+
410
+ func testMaxSqueezingAxes( ) {
411
+ // Expected gradient values were computed using the following TensorFlow Python code:
412
+ // ```
413
+ // import tensorflow as tf
414
+ // x = tf.constant(range(6), shape=(2, 3), dtype=float)
415
+ // with tf.GradientTape() as t:
416
+ // t.watch(x)
417
+ // y = tf.reduce_sum(tf.reduce_max(x, axis=0, keepdims=False))
418
+ // print(t.gradient(y, x))
419
+ // ```
420
+ func maxSqueezingAxesSum( _ x: Tensor < Float > ) -> Tensor < Float > {
421
+ x. max ( squeezingAxes: 0 ) . sum ( )
422
+ }
423
+ do {
424
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 3 , 4 , 5 ] ]
425
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: maxSqueezingAxesSum)
426
+ XCTAssertEqual ( value, maxSqueezingAxesSum ( x) )
427
+ let expectedGradient : Tensor < Float > = [ [ 0 , 0 , 0 ] , [ 1 , 1 , 1 ] ]
428
+ XCTAssertEqual ( computedGradient, expectedGradient)
429
+ }
430
+ do {
431
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 2 , 1 , 0 ] ]
432
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: maxSqueezingAxesSum)
433
+ XCTAssertEqual ( value, maxSqueezingAxesSum ( x) )
434
+ let expectedGradient : Tensor < Float > = [ [ 0 , 0.5 , 1 ] , [ 1 , 0.5 , 0 ] ]
435
+ XCTAssertEqual ( computedGradient, expectedGradient)
436
+ }
437
+ }
438
+
439
+ func testMinSqueezingAxes( ) {
440
+ // Expected gradient values were computed using the following TensorFlow Python code:
441
+ // ```
442
+ // import tensorflow as tf
443
+ // x = tf.constant(range(6), shape=(2, 3), dtype=float)
444
+ // with tf.GradientTape() as t:
445
+ // t.watch(x)
446
+ // y = tf.reduce_sum(tf.reduce_min(x, axis=0, keepdims=False))
447
+ // print(t.gradient(y, x))
448
+ // ```
449
+ func minSqueezingAxesSum( _ x: Tensor < Float > ) -> Tensor < Float > {
450
+ x. min ( squeezingAxes: 0 ) . sum ( )
451
+ }
452
+ do {
453
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 3 , 4 , 5 ] ]
454
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: minSqueezingAxesSum)
455
+ XCTAssertEqual ( value, minSqueezingAxesSum ( x) )
456
+ let expectedGradient : Tensor < Float > = [ [ 1 , 1 , 1 ] , [ 0 , 0 , 0 ] ]
457
+ XCTAssertEqual ( computedGradient, expectedGradient)
458
+ }
459
+ do {
460
+ let x : Tensor < Float > = [ [ 0 , 1 , 2 ] , [ 2 , 1 , 0 ] ]
461
+ let ( value, computedGradient) = valueWithGradient ( at: x, in: minSqueezingAxesSum)
462
+ XCTAssertEqual ( value, minSqueezingAxesSum ( x) )
463
+ let expectedGradient : Tensor < Float > = [ [ 1 , 0.5 , 0 ] , [ 0 , 0.5 , 1 ] ]
464
+ XCTAssertEqual ( computedGradient, expectedGradient)
465
+ }
466
+ }
467
+
358
468
func testTensorInitStacking( ) {
359
469
let a1 = Tensor < Float > ( [ 1 , 2 , 3 , 4 , 5 ] )
360
470
let b1 = Tensor < Float > ( [ 6 , 7 , 8 , 9 , 10 ] )
0 commit comments