Computes the number of elements in the loss function induced by `weights`. A given weights tensor induces different numbers of usable elements in the `losses` tensor. The `weights` tensor is broadcast across `losses` for all possible dimensions. For example, if `losses` is a tensor of dimensi
(losses, weights, per_batch=False)
| 88 | |
| 89 | |
| 90 | def _num_present(losses, weights, per_batch=False): |
| 91 | """Computes the number of elements in the loss function induced by `weights`. |
| 92 | |
| 93 | A given weights tensor induces different numbers of usable elements in the |
| 94 | `losses` tensor. The `weights` tensor is broadcast across `losses` for all |
| 95 | possible dimensions. For example, if `losses` is a tensor of dimension |
| 96 | `[4, 5, 6, 3]` and `weights` is a tensor of shape `[4, 5]`, then `weights` is, |
| 97 | in effect, tiled to match the shape of `losses`. Following this effective |
| 98 | tile, the total number of present elements is the number of non-zero weights. |
| 99 | |
| 100 | Args: |
| 101 | losses: `Tensor` of shape `[batch_size, d1, ... dN]`. |
| 102 | weights: `Tensor` of shape `[]`, `[batch_size]` or |
| 103 | `[batch_size, d1, ... dK]`, where K < N. |
| 104 | per_batch: Whether to return the number of elements per batch or as a sum |
| 105 | total. |
| 106 | |
| 107 | Returns: |
| 108 | The number of present (non-zero) elements in the losses tensor. If |
| 109 | `per_batch` is `True`, the value is returned as a tensor of size |
| 110 | `[batch_size]`. Otherwise, a single scalar tensor is returned. |
| 111 | """ |
| 112 | if ((isinstance(weights, float) and weights != 0.0) or |
| 113 | (context.executing_eagerly() and weights._rank() == 0 # pylint: disable=protected-access |
| 114 | and not math_ops.equal(weights, 0.0))): |
| 115 | return _num_elements(losses) |
| 116 | with ops.name_scope(None, "num_present", (losses, weights)) as scope: |
| 117 | weights = math_ops.cast(weights, dtype=dtypes.float32) |
| 118 | present = array_ops.where( |
| 119 | math_ops.equal(weights, 0.0), |
| 120 | array_ops.zeros_like(weights), |
| 121 | array_ops.ones_like(weights)) |
| 122 | present = weights_broadcast_ops.broadcast_weights(present, losses) |
| 123 | if per_batch: |
| 124 | return math_ops.reduce_sum( |
| 125 | present, |
| 126 | axis=math_ops.range(1, array_ops.rank(present)), |
| 127 | keepdims=True, |
| 128 | name=scope) |
| 129 | return math_ops.reduce_sum(present, name=scope) |
| 130 | |
| 131 | |
| 132 | def _num_elements(losses): |
no test coverage detected