SumGradHelper returns the gradient for the Sum operator, and is used by SumGrad and MeanGrad.
| 692 | // SumGradHelper returns the gradient for the Sum operator, and is used |
| 693 | // by SumGrad and MeanGrad. |
| 694 | Output SumGradHelper(const Scope& scope, const Operation& op, |
| 695 | const std::vector<Output>& grad_inputs) { |
| 696 | // The partial derivative for any input along a "reduced" dimension |
| 697 | // is just 1, so we only need replicate the output gradient on such a |
| 698 | // dimension to its "expanded" shape. |
| 699 | // Running example: |
| 700 | // input is |
| 701 | // [[a, b, c], |
| 702 | // [d, e, f]] |
| 703 | // reduction_indices = [1] |
| 704 | // Sum = [a + b + c, d + e + f] |
| 705 | // if the gradient is [g1, g2] |
| 706 | // We want the propagated gradient to be |
| 707 | // [[g1, g1, g1], |
| 708 | // [g2, g2, g2]] |
| 709 | |
| 710 | // input_shape = [2, 3] |
| 711 | auto input_shape = Shape(scope, op.input(0)); |
| 712 | |
| 713 | // output_shape_kept_dims = [2, 1] |
| 714 | auto output_shape_kept_dims = |
| 715 | ReducedShapeHelper(scope, input_shape, op.input(1)); |
| 716 | |
| 717 | // This step "flips" any 1s with values from the input_shape, and |
| 718 | // replaces remaining entries with 1. This creates a shape that |
| 719 | // shows how much each dimension in the incoming gradient should be |
| 720 | // replicated. |
| 721 | // tile_scaling = [1, 3] |
| 722 | auto tile_scaling = SafeDivHelper(scope, input_shape, output_shape_kept_dims); |
| 723 | |
| 724 | // grad = [[g1], [g2]] |
| 725 | auto grad = Reshape(scope, grad_inputs[0], output_shape_kept_dims); |
| 726 | |
| 727 | // tile(grad, tile_scaling) = [[g1, g1, g1], [g2, g2, g2]] |
| 728 | return Tile(scope, grad, tile_scaling); |
| 729 | } |
| 730 | |
| 731 | Status SumGrad(const Scope& scope, const Operation& op, |
| 732 | const std::vector<Output>& grad_inputs, |
no test coverage detected