MCPcopy Create free account
hub / github.com/alibaba/MNN / onGrad

Method onGrad

tools/train/source/grad/BinaryGrad.cpp:72–194  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

70class BinaryGrad : public OpGrad {
71public:
72 virtual std::vector<Express::VARP> onGrad(Express::EXPRP expr,
73 const std::vector<Express::VARP>& backwardOutput) override {
74 std::vector<VARP> res;
75 auto inputs = expr->inputs();
76 res.resize(inputs.size());
77 auto op = expr->get();
78 auto outputDiff = backwardOutput[0];
79 std::vector<VARP> output(expr->outputSize());
80 for (int i = 0; i < expr->outputSize(); ++i) {
81 output[i] = Variable::create(expr, i);
82 }
83 int activateType = op->main_as_BinaryOp()->activationType();
84 if (activateType == 1) { // relu
85 auto mask = _Cast<float>(_Greater(output[0], _Scalar(0.0f)));
86 outputDiff = mask * backwardOutput[0];
87 }
88 switch (op->main_as_BinaryOp()->opType()) {
89 case BinaryOpOperation_ADD: {
90 res[0] = outputDiff;
91 res[1] = outputDiff;
92 break;
93 }
94 case BinaryOpOperation_SUB: {
95 res[0] = outputDiff;
96 res[1] = _Negative(outputDiff);
97 break;
98 }
99 case BinaryOpOperation_MUL: {
100 res[0] = outputDiff * inputs[1];
101 res[1] = outputDiff * inputs[0];
102 break;
103 }
104 case BinaryOpOperation_MAXIMUM: {
105 auto mask0 = _Sign(inputs[0] - output[0]) + _Const(1.0f, {}, NCHW);
106 auto mask1 = _Sign(inputs[1] - output[0]) + _Const(1.0f, {}, NCHW);
107 auto maskSum = mask0 + mask1;
108 res[0] = outputDiff * mask0 / maskSum;
109 res[1] = outputDiff * mask1 / maskSum;
110 break;
111 }
112 case BinaryOpOperation_MINIMUM: {
113 auto mask0 = _Sign(output[0] - inputs[0]) + _Const(1.0f, {}, NCHW);
114 auto mask1 = _Sign(output[0] - inputs[1]) + _Const(1.0f, {}, NCHW);
115 auto maskSum = mask0 + mask1;
116 res[0] = outputDiff * mask0 / maskSum;
117 res[1] = outputDiff * mask1 / maskSum;
118 break;
119 }
120 case BinaryOpOperation_REALDIV: {
121 res[0] = _Divide(outputDiff, inputs[1]);
122 // d (u / v) = dx / v , -dx*u(1/v)*(1/v)
123 res[1] = _Negative(_Multiply(outputDiff, _Divide(output[0], inputs[1])));
124 break;
125 }
126 case BinaryOpOperation_POW: {
127 // d (pow(x, y)) = dv * pow(x, y) / x * y , dv * pow(x, y) * ln(x)
128 res[0] = outputDiff * output[0] * OpGrad::divideAvoidZero(inputs[1], inputs[0]);
129 res[1] = outputDiff * output[0] * _Log(inputs[0]);

Callers

nothing calls this directly

Calls 15

_GreaterFunction · 0.85
_NegativeFunction · 0.85
_SignFunction · 0.85
_ConstFunction · 0.85
_DivideFunction · 0.85
_MultiplyFunction · 0.85
_LogFunction · 0.85
_ReduceSumFunction · 0.85
createFunction · 0.50
_ScalarFunction · 0.50
_SquareFunction · 0.50
resizeMethod · 0.45

Tested by

no test coverage detected