Computes the weighted loss. Args: losses: `Tensor` of shape `[batch_size, d1, ... dN]`. weights: Optional `Tensor` whose rank is either 0, or the same rank as `losses`, and must be broadcastable to `losses` (i.e., all dimensions must be either `1`, or the same as the correspon
(
losses, weights=1.0, scope=None, loss_collection=ops.GraphKeys.LOSSES,
reduction=Reduction.SUM_BY_NONZERO_WEIGHTS)
| 137 | |
| 138 | @tf_export(v1=["losses.compute_weighted_loss"]) |
| 139 | def compute_weighted_loss( |
| 140 | losses, weights=1.0, scope=None, loss_collection=ops.GraphKeys.LOSSES, |
| 141 | reduction=Reduction.SUM_BY_NONZERO_WEIGHTS): |
| 142 | """Computes the weighted loss. |
| 143 | |
| 144 | Args: |
| 145 | losses: `Tensor` of shape `[batch_size, d1, ... dN]`. |
| 146 | weights: Optional `Tensor` whose rank is either 0, or the same rank as |
| 147 | `losses`, and must be broadcastable to `losses` (i.e., all dimensions must |
| 148 | be either `1`, or the same as the corresponding `losses` dimension). |
| 149 | scope: the scope for the operations performed in computing the loss. |
| 150 | loss_collection: the loss will be added to these collections. |
| 151 | reduction: Type of reduction to apply to loss. |
| 152 | |
| 153 | Returns: |
| 154 | Weighted loss `Tensor` of the same type as `losses`. If `reduction` is |
| 155 | `NONE`, this has the same shape as `losses`; otherwise, it is scalar. |
| 156 | |
| 157 | Raises: |
| 158 | ValueError: If `weights` is `None` or the shape is not compatible with |
| 159 | `losses`, or if the number of dimensions (rank) of either `losses` or |
| 160 | `weights` is missing. |
| 161 | |
| 162 | Note: |
| 163 | When calculating the gradient of a weighted loss contributions from |
| 164 | both `losses` and `weights` are considered. If your `weights` depend |
| 165 | on some model parameters but you do not want this to affect the loss |
| 166 | gradient, you need to apply `tf.stop_gradient` to `weights` before |
| 167 | passing them to `compute_weighted_loss`. |
| 168 | |
| 169 | @compatibility(eager) |
| 170 | The `loss_collection` argument is ignored when executing eagerly. Consider |
| 171 | holding on to the return value or collecting losses via a `tf.keras.Model`. |
| 172 | @end_compatibility |
| 173 | """ |
| 174 | Reduction.validate(reduction) |
| 175 | with ops.name_scope(scope, "weighted_loss", (losses, weights)): |
| 176 | # Save the `reduction` argument for loss normalization when distributing |
| 177 | # to multiple replicas. Used only for estimator + v1 optimizer flow. |
| 178 | ops.get_default_graph()._last_loss_reduction = reduction # pylint: disable=protected-access |
| 179 | |
| 180 | with ops.control_dependencies(( |
| 181 | weights_broadcast_ops.assert_broadcastable(weights, losses),)): |
| 182 | losses = ops.convert_to_tensor(losses) |
| 183 | input_dtype = losses.dtype |
| 184 | losses = math_ops.cast(losses, dtype=dtypes.float32) |
| 185 | weights = math_ops.cast(weights, dtype=dtypes.float32) |
| 186 | weighted_losses = math_ops.multiply(losses, weights) |
| 187 | if reduction == Reduction.NONE: |
| 188 | loss = weighted_losses |
| 189 | else: |
| 190 | loss = math_ops.reduce_sum(weighted_losses) |
| 191 | if reduction == Reduction.MEAN: |
| 192 | loss = _safe_mean( |
| 193 | loss, math_ops.reduce_sum(array_ops.ones_like(losses) * weights)) |
| 194 | elif (reduction == Reduction.SUM_BY_NONZERO_WEIGHTS or |
| 195 | reduction == Reduction.SUM_OVER_NONZERO_WEIGHTS): |
| 196 | loss = _safe_mean(loss, _num_present(losses, weights)) |
no test coverage detected