aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/eager/backprop_test.py
diff options
context:
space:
mode:
authorGravatar Akshay Modi <nareshmodi@google.com>2018-09-05 22:34:52 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-09-05 22:43:35 -0700
commite23d522e943309cefae368a11c21ae37b6986165 (patch)
tree959f83e6128e87734b837082164fb88dc3803ca9 /tensorflow/python/eager/backprop_test.py
parent5393c8f0dc57857c93482bff67f1134aae9af594 (diff)
Allow creating a py EagerTensor that shares the underlying TensorHandle.
This is so that gradients with respect to scalars pass (see the test added in backprop_test.py). A micro benchmark just calling constant_op.constant slows down a bit - this is inevitable as we are creating a new python object. After: walltime: ~2.1 Before: walltime: ~1.47 Linear regression benchmark is pretty much unchanged. PiperOrigin-RevId: 211753801
Diffstat (limited to 'tensorflow/python/eager/backprop_test.py')
-rw-r--r--tensorflow/python/eager/backprop_test.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/tensorflow/python/eager/backprop_test.py b/tensorflow/python/eager/backprop_test.py
index 6673178ee7..3319b440b4 100644
--- a/tensorflow/python/eager/backprop_test.py
+++ b/tensorflow/python/eager/backprop_test.py
@@ -957,5 +957,45 @@ class BackpropTest(test.TestCase):
self.assertAllEqual(grad1, grad2)
+ @test_util.run_in_graph_and_eager_modes
+ def testDifferentiatingScalarCache(self):
+ # In the following test, if x2 = x1 (i.e the objects are the exact same),
+ # then y is essentially, 2*x1, and dy/dx1 = 2.
+ # When we had a pure scalar cache in eager, this would be the case. This
+ # test prevents us from going back to that case.
+ with backprop.GradientTape(persistent=False) as g:
+ x1 = constant_op.constant(3.0)
+ x2 = constant_op.constant(3.0)
+ g.watch(x1)
+ g.watch(x2)
+ y = x1 + x2
+ grad = g.gradient(target=y, sources=[x1])
+ self.assertEqual(self.evaluate(grad), [1.0])
+
+ def testVariablesAndConstantsProduceTheSameGradients(self):
+
+ # In the following test, differentiating [y, z] against [a, b] gives:
+ # (dy/da + dz/da, dy/db + dz/db).
+ # If a and b are the same constant, dz/da will not be 0 (which it should
+ # be).
+ # This is solved by using variable since doing a read_value on a tensor will
+ # produce a new tensor and corresponding TensorHandle, and not reuse the
+ # same tensor (which would happen if we are using a cache and reusing
+ # EagerTensor objects).
+ def get_grads(a, b):
+ with backprop.GradientTape() as tape:
+ tape.watch([a, b])
+ y = a**3
+ z = b**2
+ return tape.gradient([y, z], [a, b])
+
+ gradients_constants = get_grads(
+ constant_op.constant(2.0), constant_op.constant(2.0))
+ gradients_variables = get_grads(
+ resource_variable_ops.ResourceVariable(2.0),
+ resource_variable_ops.ResourceVariable(2.0))
+ self.assertAllEqual(gradients_constants, gradients_variables)
+
+
if __name__ == '__main__':
test.main()