array_grad_test.cc revision ccb22083570219884f871d30a7124d93c151ef70
1/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2 3Licensed under the Apache License, Version 2.0 (the "License"); 4you may not use this file except in compliance with the License. 5You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9Unless required by applicable law or agreed to in writing, software 10distributed under the License is distributed on an "AS IS" BASIS, 11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12See the License for the specific language governing permissions and 13limitations under the License. 14==============================================================================*/ 15 16#include "tensorflow/cc/framework/grad_op_registry.h" 17#include "tensorflow/cc/framework/gradient_checker.h" 18#include "tensorflow/cc/framework/testutil.h" 19#include "tensorflow/cc/gradients/grad_testutil.h" 20#include "tensorflow/cc/ops/standard_ops.h" 21#include "tensorflow/core/framework/tensor_testutil.h" 22#include "tensorflow/core/lib/core/status_test_util.h" 23 24namespace tensorflow { 25using namespace ops; // NOLINT(build/namespaces) 26 27namespace { 28 29class ArrayGradTest : public ::testing::Test { 30 protected: 31 ArrayGradTest() : scope_(Scope::NewRootScope()) {} 32 33 void RunTest(const Output& x, const TensorShape& x_shape, const Output& y, 34 const TensorShape& y_shape) { 35 TF_ASSERT_OK(scope_.status()); 36 float max_error; 37 TF_ASSERT_OK(ComputeGradientError(scope_, {x}, {x_shape}, {y}, {y_shape}, 38 &max_error)); 39 EXPECT_LT(max_error, 1e-4); 40 } 41 42 void RunTest(const OutputList& xs, const std::vector<TensorShape>& x_shapes, 43 const OutputList& ys, const std::vector<TensorShape>& y_shapes) { 44 TF_ASSERT_OK(scope_.status()); 45 float max_error; 46 TF_ASSERT_OK( 47 ComputeGradientError(scope_, xs, x_shapes, ys, y_shapes, &max_error)); 48 EXPECT_LT(max_error, 1e-4); 49 } 50 51 Scope scope_; 52}; 53 54TEST_F(ArrayGradTest, PackGrad_Axis0) { 55 TensorShape x_shape({1, 2, 3}); 56 std::vector<Output> xs; 57 xs.push_back(Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape))); 58 xs.push_back(Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape))); 59 auto y = Pack(scope_, xs, Pack::Axis(0)); 60 TensorShape y_shape({2, 1, 2, 3}); 61 RunTest(xs, {x_shape, x_shape}, {y}, {y_shape}); 62} 63 64TEST_F(ArrayGradTest, PackGrad_Axis1) { 65 TensorShape x_shape({1, 2, 3}); 66 std::vector<Output> xs; 67 xs.push_back(Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape))); 68 xs.push_back(Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape))); 69 auto y = Pack(scope_, xs, Pack::Axis(1)); 70 TensorShape y_shape({1, 2, 2, 3}); 71 RunTest(xs, {x_shape, x_shape}, {y}, {y_shape}); 72} 73 74TEST_F(ArrayGradTest, UnpackGrad_Axis0) { 75 TensorShape x_shape({4, 2, 3}); 76 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 77 // Unpacking the first dimension results in 4 outputs. 78 std::vector<TensorShape> y_shapes(4, TensorShape({2, 3})); 79 auto y = Unpack(scope_, x, 4, Unpack::Axis(0)); 80 RunTest({x}, {x_shape}, y.output, y_shapes); 81} 82 83TEST_F(ArrayGradTest, UnpackGrad_Axis1) { 84 TensorShape x_shape({4, 2, 3}); 85 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 86 // Unpacking the second dimension results in 2 outputs. 87 std::vector<TensorShape> y_shapes(2, TensorShape({4, 3})); 88 auto y = Unpack(scope_, x, 2, Unpack::Axis(1)); 89 RunTest({x}, {x_shape}, y.output, y_shapes); 90} 91 92TEST_F(ArrayGradTest, IdentityGrad) { 93 TensorShape shape({5, 2}); 94 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(shape)); 95 auto y = Identity(scope_, x); 96 RunTest(x, shape, y, shape); 97} 98 99TEST_F(ArrayGradTest, SplitGrad) { 100 TensorShape x_shape({5, 2}); 101 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 102 // Split along the second dimension. 103 auto split_dim = Const(scope_, 1, {}); 104 auto y = Split(scope_, split_dim, x, /* num_split */ 2); 105 TensorShape y_shape = TensorShape({5, 1}); 106 RunTest({x}, {x_shape}, y.output, {y_shape, y_shape}); 107} 108 109TEST_F(ArrayGradTest, DiagGrad) { 110 TensorShape x_shape({5, 2}); 111 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 112 auto y = Diag(scope_, x); 113 TensorShape y_shape({5, 2, 5, 2}); 114 RunTest(x, x_shape, y, y_shape); 115} 116 117TEST_F(ArrayGradTest, DiagPartGrad) { 118 TensorShape x_shape({5, 2, 5, 2}); 119 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 120 auto y = DiagPart(scope_, x); 121 TensorShape y_shape({5, 2}); 122 RunTest(x, x_shape, y, y_shape); 123} 124 125TEST_F(ArrayGradTest, MatrixDiagGrad) { 126 TensorShape x_shape({5, 2}); 127 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 128 auto y = MatrixDiag(scope_, x); 129 TensorShape y_shape({5, 2, 2}); 130 RunTest(x, x_shape, y, y_shape); 131} 132 133TEST_F(ArrayGradTest, MatrixBandPartGrad) { 134 TensorShape shape({5, 5}); 135 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(shape)); 136 const int64 num_lower = 1; 137 const int64 num_upper = 2; 138 auto y = MatrixBandPart(scope_, x, num_lower, num_upper); 139 RunTest(x, shape, y, shape); 140} 141 142TEST_F(ArrayGradTest, GatherNdGrad_SimpleIndexing) { 143 TensorShape x_shape({2, 2}); 144 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 145 auto indices = Const(scope_, {{0, 0}, {1, 1}}); 146 TensorShape y_shape({2}); 147 auto y = GatherNd(scope_, x, indices); 148 RunTest(x, x_shape, y, y_shape); 149} 150 151TEST_F(ArrayGradTest, GatherNdGrad_SliceIndexing) { 152 TensorShape shape({2, 2}); 153 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(shape)); 154 auto indices = Const(scope_, {{1}, {0}}); 155 auto y = GatherNd(scope_, x, indices); 156 RunTest(x, shape, y, shape); 157} 158 159TEST_F(ArrayGradTest, CheckNumericsGrad) { 160 TensorShape shape({5, 2}); 161 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(shape)); 162 auto y = CheckNumerics(scope_, x, "CheckNumerics failed"); 163 RunTest(x, shape, y, shape); 164} 165 166TEST_F(ArrayGradTest, ReshapeGrad) { 167 TensorShape x_shape({5, 2}); 168 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 169 TensorShape y_shape({2, 5}); 170 auto y = Reshape(scope_, x, {2, 5}); 171 RunTest(x, x_shape, y, y_shape); 172} 173 174TEST_F(ArrayGradTest, ExpandDimsGrad) { 175 TensorShape x_shape({5, 2}); 176 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 177 TensorShape y_shape({1, 5, 2}); 178 auto y = ExpandDims(scope_, x, 0); 179 RunTest(x, x_shape, y, y_shape); 180} 181 182TEST_F(ArrayGradTest, SqueezeGrad) { 183 TensorShape x_shape({1, 5, 1, 2}); 184 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 185 TensorShape y_shape({5, 2}); 186 auto y = Squeeze(scope_, x); 187 RunTest(x, x_shape, y, y_shape); 188} 189 190TEST_F(ArrayGradTest, TransposeGrad) { 191 TensorShape x_shape({5, 2}); 192 auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(x_shape)); 193 TensorShape y_shape({2, 5}); 194 auto y = Transpose(scope_, x, {1, 0}); 195 RunTest(x, x_shape, y, y_shape); 196} 197 198} // namespace 199} // namespace tensorflow 200