pad gradient (#7926)

Co-authored-by: zhijxu <zhijxu@microsoft.com>
This commit is contained in:
Vincent Wang 2021-06-04 02:05:41 +08:00 committed by GitHub
parent 3bb780dcd5
commit a118da160d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 1 deletions

View file

@ -67,7 +67,8 @@ static std::unordered_map<std::string, std::unordered_set<size_t>>
{"Unsqueeze", {1}},
{"ReduceSum", {1}},
{"Split", {1}},
{"Clip", {1, 2}}};
{"Clip", {1, 2}},
{"Pad", {1, 2}}};
class GradientGraphBuilder {
public:

View file

@ -1666,5 +1666,20 @@ IMPLEMENT_GRADIENT_BUILDER(GetATenOpGradient) {
return std::vector<NodeDef>{NodeDef(OpDef{"ATenOpGrad", kMSDomain, 1}, input_args, output_args, attrs)};
}
IMPLEMENT_GRADIENT_BUILDER(GetPadGradient) {
const auto& attributes = SrcNodeAttributes();
std::string mode = "constant";
if (attributes.find("mode") != attributes.end() && utils::HasString(attributes.at("mode"))) {
mode = attributes.at("mode").s();
}
if (mode != "constant") {
ORT_THROW("Pad gradient currently supports constant mode only.");
}
return std::vector<NodeDef>{NodeDef("Neg", {I(1)}, {IA("Neg_pads")}),
NodeDef("Pad", {GO(0), IA("Neg_pads")}, {GI(0)})};
}
} // namespace training
} // namespace onnxruntime

View file

@ -73,6 +73,7 @@ DECLARE_GRADIENT_BUILDER(GetAbsGradient)
DECLARE_GRADIENT_BUILDER(GetMinMaxGradient)
DECLARE_GRADIENT_BUILDER(GetTileGradient)
DECLARE_GRADIENT_BUILDER(GetATenOpGradient)
DECLARE_GRADIENT_BUILDER(GetPadGradient)
DECLARE_GRADIENT_BUILDER(GetIdentityGradient)
} // namespace training

View file

@ -105,6 +105,7 @@ void GradientBuilderRegistry::RegisterGradientBuilders() {
REGISTER_GRADIENT_BUILDER("Max", GetMinMaxGradient);
REGISTER_GRADIENT_BUILDER("Tile", GetTileGradient);
REGISTER_GRADIENT_BUILDER("ATenOp", GetATenOpGradient);
REGISTER_GRADIENT_BUILDER("Pad", GetPadGradient);
REGISTER_GRADIENT_BUILDER("Identity", GetIdentityGradient);
};

View file

@ -2580,6 +2580,75 @@ TEST(GradientCheckerTest, TileGrad) {
}
}
TEST(GradientCheckerTest, PadGrad) {
float max_error;
GradientChecker<float, float, float> gradient_checker;
OpDef op_def{"Pad", kOnnxDomain, 11};
{
TensorInfo x_info({2, 4}, true);
TensorInfo pads_info({4}, false, nullptr, DataTypeImpl::GetTensorType<int64_t>());
std::vector<std::vector<float>> x_datas = {{1, 2, 3, 4, 5, 6, 7, 8}, {0, 2, 2, 0}};
TensorInfo y_info({4, 6}, true);
gradient_checker.ComputeGradientError(op_def, {x_info, pads_info}, {y_info}, &max_error, x_datas);
EXPECT_IS_TINY(max_error);
}
{
TensorInfo x_info({2, 4}, true);
TensorInfo pads_info({4}, false, nullptr, DataTypeImpl::GetTensorType<int64_t>());
std::vector<std::vector<float>> x_datas = {{1, 2, 3, 4, 5, 6, 7, 8}, {0, -2, 2, 0}};
TensorInfo y_info({4, 2}, true);
gradient_checker.ComputeGradientError(op_def, {x_info, pads_info}, {y_info}, &max_error, x_datas,
{MakeAttribute("mode", "constant")});
EXPECT_IS_TINY(max_error);
}
{
TensorInfo x_info({2, 4}, true);
TensorInfo pads_info({4}, false, nullptr, DataTypeImpl::GetTensorType<int64_t>());
std::vector<std::vector<float>> x_datas = {{1, 2, 3, 4, 5, 6, 7, 8}, {0, 2, 2, 0}};
TensorInfo y_info({4, 6}, true);
bool has_error = false;
try {
gradient_checker.ComputeGradientError(op_def, {x_info, pads_info}, {y_info}, &max_error, x_datas,
{MakeAttribute("mode", "reflect")});
} catch (const std::exception& ex) {
auto ret = std::string(ex.what()).find("Pad gradient currently supports constant mode only.");
ASSERT_TRUE(ret != std::string::npos);
has_error = true;
}
ASSERT_TRUE(has_error);
}
{
TensorInfo x_info({2, 4}, true);
TensorInfo pads_info({4}, false, nullptr, DataTypeImpl::GetTensorType<int64_t>());
std::vector<std::vector<float>> x_datas = {{1, 2, 3, 4, 5, 6, 7, 8}, {0, 2, 2, 0}};
TensorInfo y_info({4, 6}, true);
bool has_error = false;
try {
gradient_checker.ComputeGradientError(op_def, {x_info, pads_info}, {y_info}, &max_error, x_datas,
{MakeAttribute("mode", "edge")});
} catch (const std::exception& ex) {
auto ret = std::string(ex.what()).find("Pad gradient currently supports constant mode only.");
ASSERT_TRUE(ret != std::string::npos);
has_error = true;
}
ASSERT_TRUE(has_error);
}
}
} // namespace test
} // namespace onnxruntime