diff options
author | A. Unique TensorFlower <gardener@tensorflow.org> | 2018-09-26 17:42:47 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-09-26 17:46:19 -0700 |
commit | 7b88cabfec45c9e04ab3d9cf1c2411c6dce4c694 (patch) | |
tree | 9bdc598fa33808d8689299438a50ad7445ebdec5 /tensorflow/core/ops | |
parent | bfda65cc70526c919c57ef8321dd282e463ed8a3 (diff) |
Add xlogy and xdivy op.
PiperOrigin-RevId: 214700693
Diffstat (limited to 'tensorflow/core/ops')
-rw-r--r-- | tensorflow/core/ops/math_grad.cc | 34 | ||||
-rw-r--r-- | tensorflow/core/ops/math_grad_test.cc | 40 | ||||
-rw-r--r-- | tensorflow/core/ops/math_ops.cc | 14 |
3 files changed, 88 insertions, 0 deletions
diff --git a/tensorflow/core/ops/math_grad.cc b/tensorflow/core/ops/math_grad.cc index 07f876cb90..55dcc50325 100644 --- a/tensorflow/core/ops/math_grad.cc +++ b/tensorflow/core/ops/math_grad.cc @@ -549,6 +549,40 @@ Status PowGrad(const AttrSlice& attrs, FunctionDef* g) { } REGISTER_OP_GRADIENT("Pow", PowGrad); +Status XlogyGrad(const AttrSlice& attrs, FunctionDef* g) { + // clang-format off + return GradForBinaryCwise(g, { + {{"zeros"}, "ZerosLike", {"x"}}, + {{"is_x_zero"}, "NotEqual", {"x", "zeros"}}, + {{"is_zero_cast"}, "Cast", {"is_x_zero"}, + {{"SrcT", DT_BOOL}, {"DstT", "$T"}}}, + {{"safe_logy"}, "Xlogy", {"is_zero_cast", "y"}}, + {{"xlogygrad"}, "Xdivy", {"x", "y"}}, + {{"gx"}, "Mul", {"safe_logy", "dz"}}, + {{"gy"}, "Mul", {"xlogygrad", "dz"}}, + }); + // clang-format on +} +REGISTER_OP_GRADIENT("Xlogy", XlogyGrad); + +Status XdivyGrad(const AttrSlice& attrs, FunctionDef* g) { + // clang-format off + return GradForBinaryCwise(g, { + {{"zeros"}, "ZerosLike", {"x"}}, + {{"is_x_zero"}, "NotEqual", {"x", "zeros"}}, + {{"is_zero_cast"}, "Cast", {"is_x_zero"}, + {{"SrcT", DT_BOOL}, {"DstT", "$T"}}}, + {{"safe_divy"}, "Xdivy", {"is_zero_cast", "y"}}, + {{"y2"}, "Square", {"y"}}, + {{"negy2"}, "Neg", {"y2"}}, + {{"xdivygrad"}, "Xdivy", {"x", "negy2"}}, + {{"gx"}, "Mul", {"safe_divy", "dz"}}, + {{"gy"}, "Mul", {"xdivygrad", "dz"}}, + }); + // clang-format on +} +REGISTER_OP_GRADIENT("Xdivy", XdivyGrad); + Status MaximumMinimumGradHelper(const string& comparator, const AttrSlice& attrs, FunctionDef* g) { // clang-format off diff --git a/tensorflow/core/ops/math_grad_test.cc b/tensorflow/core/ops/math_grad_test.cc index 5ee79809ac..9fc6b34147 100644 --- a/tensorflow/core/ops/math_grad_test.cc +++ b/tensorflow/core/ops/math_grad_test.cc @@ -909,6 +909,46 @@ TEST_F(MathGradTest, ComplexPow) { } #endif // TENSORFLOW_USE_SYCL +TEST_F(MathGradTest, Xlogy) { + auto x = test::AsTensor<float>({0.f, 0.f, 2.f, 3.f, 4.f, 5.f}, + TensorShape({2, 3})); + auto y = test::AsTensor<float>({.5f, 2.f}, TensorShape({2, 1})); + Tensor dx; + Tensor dy; + auto g = [](float x, float y) -> float { return x == 0. ? 0. : std::log(y); }; + auto h = [](float x, float y) -> float { return x == 0. ? 0. : x / y; }; + SymGrad("Xlogy", x, y, &dx, &dy); + test::ExpectClose( + dx, test::AsTensor<float>({g(0.f, .5f), g(0.f, 0.f), g(2.f, .5f), + g(3.f, 2.f), g(4.f, 2.f), g(5.f, 2.f)}, + TensorShape({2, 3}))); + test::ExpectClose( + dy, test::AsTensor<float>({h(0.f, .5f) + h(0.f, 0.f) + h(2.f, .5f), + h(3.f, 2.f) + h(4.f, 2.f) + h(5.f, 2.f)}, + TensorShape({2, 1}))); +} + +TEST_F(MathGradTest, Xdivy) { + auto x = test::AsTensor<float>({0.f, 0.f, 2.f, 3.f, 4.f, 5.f}, + TensorShape({2, 3})); + auto y = test::AsTensor<float>({.5f, 2.f}, TensorShape({2, 1})); + Tensor dx; + Tensor dy; + auto g = [](float x, float y) -> float { return x == 0. ? 0. : 1 / y; }; + auto h = [](float x, float y) -> float { + return x == 0. ? 0. : -x / (y * y); + }; + SymGrad("Xdivy", x, y, &dx, &dy); + test::ExpectClose( + dx, test::AsTensor<float>({g(0.f, .5f), g(0.f, 0.f), g(2.f, .5f), + g(3.f, 2.f), g(4.f, 2.f), g(5.f, 2.f)}, + TensorShape({2, 3}))); + test::ExpectClose( + dy, test::AsTensor<float>({h(0.f, .5f) + h(0.f, 0.f) + h(2.f, .5f), + h(3.f, 2.f) + h(4.f, 2.f) + h(5.f, 2.f)}, + TensorShape({2, 1}))); +} + TEST_F(MathGradTest, Maximum) { auto x = test::AsTensor<float>({-3.f, -2.f, -1.f, 1.f, 2.f, 3.f}, TensorShape({2, 3})); diff --git a/tensorflow/core/ops/math_ops.cc b/tensorflow/core/ops/math_ops.cc index 717263a9b0..3eff728f03 100644 --- a/tensorflow/core/ops/math_ops.cc +++ b/tensorflow/core/ops/math_ops.cc @@ -429,6 +429,20 @@ Returns (x - y)(x - y) element-wise. [here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); +REGISTER_OP("Xlogy") + .Input("x: T") + .Input("y: T") + .Output("z: T") + .Attr("T: {half, float, double, complex64, complex128}") + .SetShapeFn(shape_inference::BroadcastBinaryOpShapeFn); + +REGISTER_OP("Xdivy") + .Input("x: T") + .Input("y: T") + .Output("z: T") + .Attr("T: {half, float, double, complex64, complex128}") + .SetShapeFn(shape_inference::BroadcastBinaryOpShapeFn); + #undef BINARY_FEWER #undef BINARY_MORE |