Calculates the loss for a given model. Arguments: model: The model on which metrics are being calculated. inputs: Either a dictionary of inputs to the model or a list of input arrays. targets: List of target arrays. output_loss_metrics: List of metrics that are use
(model,
inputs,
targets,
output_loss_metrics=None,
sample_weights=None,
training=False)
| 83 | |
| 84 | |
| 85 | def _model_loss(model, |
| 86 | inputs, |
| 87 | targets, |
| 88 | output_loss_metrics=None, |
| 89 | sample_weights=None, |
| 90 | training=False): |
| 91 | """Calculates the loss for a given model. |
| 92 | |
| 93 | Arguments: |
| 94 | model: The model on which metrics are being calculated. |
| 95 | inputs: Either a dictionary of inputs to the model or a list of input |
| 96 | arrays. |
| 97 | targets: List of target arrays. |
| 98 | output_loss_metrics: List of metrics that are used to aggregated output |
| 99 | loss values. |
| 100 | sample_weights: Optional list of sample weight arrays. |
| 101 | training: Whether the model should be run in inference or training mode. |
| 102 | |
| 103 | Returns: |
| 104 | Returns the model output, total loss, loss value calculated using the |
| 105 | specified loss function and masks for each output. The total loss includes |
| 106 | regularization losses and applies masking and sample weighting |
| 107 | to the loss value. |
| 108 | """ |
| 109 | # TODO(psv): Dedup code here with graph mode prepare_total_loss() fn. |
| 110 | # Used to keep track of the total loss value (stateless). |
| 111 | # eg., total_loss = loss_weight_1 * output_1_loss_fn(...) + |
| 112 | # loss_weight_2 * output_2_loss_fn(...) + |
| 113 | # layer losses. |
| 114 | total_loss = 0 |
| 115 | kwargs = {} |
| 116 | if model._expects_training_arg: |
| 117 | kwargs['training'] = training |
| 118 | if len(inputs) == 1 and not isinstance(inputs, dict): |
| 119 | inputs = inputs[0] |
| 120 | |
| 121 | # Allow mixed `NumPy` and `EagerTensor` input here. |
| 122 | if any( |
| 123 | isinstance(input_t, (np.ndarray, float, int)) |
| 124 | for input_t in nest.flatten(inputs)): |
| 125 | inputs = nest.map_structure(ops.convert_to_tensor, inputs) |
| 126 | |
| 127 | outs = model(inputs, **kwargs) |
| 128 | outs = nest.flatten(outs) |
| 129 | |
| 130 | if targets: |
| 131 | targets = training_utils.cast_if_floating_dtype_and_mismatch(targets, outs) |
| 132 | # TODO(sallymatson/psv): check if we should do same mismatch fix for weights |
| 133 | if sample_weights: |
| 134 | sample_weights = [ |
| 135 | training_utils.cast_if_floating_dtype(ops.convert_to_tensor(val)) |
| 136 | if val is not None else None for val in sample_weights |
| 137 | ] |
| 138 | |
| 139 | masks = [getattr(t, '_keras_mask', None) for t in outs] |
| 140 | targets = nest.flatten(targets) |
| 141 | |
| 142 | # Used to keep track of individual output losses. |