Factor out the code for the gradient of Maximum or Minimum.
(op, grad, selector_op)
| 1397 | |
| 1398 | |
| 1399 | def _MaximumMinimumGrad(op, grad, selector_op): |
| 1400 | """Factor out the code for the gradient of Maximum or Minimum.""" |
| 1401 | y = op.inputs[1] |
| 1402 | skip_input_indices = None |
| 1403 | try: |
| 1404 | skip_input_indices = op.skip_input_indices |
| 1405 | if skip_input_indices is not None and 1 in skip_input_indices and _IsScalar( |
| 1406 | y): |
| 1407 | # When we want to get gradients for the first input only, and the second |
| 1408 | # input tensor is a scalar, we can do a much simpler calculation |
| 1409 | return _MaximumMinimumGradInputOnly(op, grad, selector_op) |
| 1410 | except AttributeError: |
| 1411 | # No gradient skipping, so do the full gradient computation |
| 1412 | pass |
| 1413 | x = op.inputs[0] |
| 1414 | gdtype = grad.dtype |
| 1415 | sx = array_ops.shape(x) |
| 1416 | sy = array_ops.shape(y) |
| 1417 | gradshape = array_ops.shape(grad) |
| 1418 | zeros = array_ops.zeros(gradshape, gdtype) |
| 1419 | xmask = selector_op(x, y) |
| 1420 | rx, ry = gen_array_ops.broadcast_gradient_args(sx, sy) |
| 1421 | if skip_input_indices is not None and 0 in skip_input_indices: |
| 1422 | gx = None |
| 1423 | else: |
| 1424 | xgrad = array_ops.where(xmask, grad, zeros) |
| 1425 | gx = array_ops.reshape(math_ops.reduce_sum(xgrad, rx), sx) |
| 1426 | |
| 1427 | if skip_input_indices is not None and 1 in skip_input_indices: |
| 1428 | gy = None |
| 1429 | else: |
| 1430 | ygrad = array_ops.where(xmask, zeros, grad) |
| 1431 | gy = array_ops.reshape(math_ops.reduce_sum(ygrad, ry), sy) |
| 1432 | |
| 1433 | return (gx, gy) |
| 1434 | |
| 1435 | |
| 1436 | @ops.RegisterGradient("Maximum") |
no test coverage detected