Adds metric tensor to the layer. Args: value: Metric tensor. aggregation: Sample-wise metric reduction function. If `aggregation=None`, it indicates that the metric tensor provided has been aggregated already. eg, `bin_acc = BinaryAccuracy(name='acc')` followed by
(self, value, aggregation=None, name=None)
| 1171 | |
| 1172 | @doc_controls.for_subclass_implementers |
| 1173 | def add_metric(self, value, aggregation=None, name=None): |
| 1174 | """Adds metric tensor to the layer. |
| 1175 | |
| 1176 | Args: |
| 1177 | value: Metric tensor. |
| 1178 | aggregation: Sample-wise metric reduction function. If `aggregation=None`, |
| 1179 | it indicates that the metric tensor provided has been aggregated |
| 1180 | already. eg, `bin_acc = BinaryAccuracy(name='acc')` followed by |
| 1181 | `model.add_metric(bin_acc(y_true, y_pred))`. If aggregation='mean', the |
| 1182 | given metric tensor will be sample-wise reduced using `mean` function. |
| 1183 | eg, `model.add_metric(tf.reduce_sum(outputs), name='output_mean', |
| 1184 | aggregation='mean')`. |
| 1185 | name: String metric name. |
| 1186 | |
| 1187 | Raises: |
| 1188 | ValueError: If `aggregation` is anything other than None or `mean`. |
| 1189 | """ |
| 1190 | if aggregation is not None and aggregation != 'mean': |
| 1191 | raise ValueError( |
| 1192 | 'We currently support only `mean` sample-wise metric aggregation. ' |
| 1193 | 'You provided aggregation=`%s`' % aggregation) |
| 1194 | |
| 1195 | from_metric_obj = hasattr(value, '_metric_obj') |
| 1196 | is_symbolic = tf_utils.is_symbolic_tensor(value) |
| 1197 | in_call_context = base_layer_utils.call_context().in_call |
| 1198 | |
| 1199 | if name is None and not from_metric_obj: |
| 1200 | # Eg. `self.add_metric(math_ops.reduce_sum(x), aggregation='mean')` |
| 1201 | # In eager mode, we use metric name to lookup a metric. Without a name, |
| 1202 | # a new Mean metric wrapper will be created on every model/layer call. |
| 1203 | # So, we raise an error when no name is provided. |
| 1204 | # We will do the same for symbolic mode for consistency although a name |
| 1205 | # will be generated if no name is provided. |
| 1206 | |
| 1207 | # We will not raise this error in the foll use case for the sake of |
| 1208 | # consistency as name in provided in the metric constructor. |
| 1209 | # mean = metrics.Mean(name='my_metric') |
| 1210 | # model.add_metric(mean(outputs)) |
| 1211 | raise ValueError('Please provide a name for your metric like ' |
| 1212 | '`self.add_metric(tf.reduce_sum(inputs), ' |
| 1213 | 'name=\'mean_activation\', aggregation=\'mean\')`') |
| 1214 | elif from_metric_obj: |
| 1215 | name = value._metric_obj.name |
| 1216 | |
| 1217 | if in_call_context: |
| 1218 | # TF Function path should take the eager path. |
| 1219 | if is_symbolic and not base_layer_utils.is_in_tf_function(): |
| 1220 | self._symbolic_add_metric(value, aggregation, name) |
| 1221 | else: |
| 1222 | self._eager_add_metric(value, aggregation, name) |
| 1223 | else: |
| 1224 | if not is_symbolic: |
| 1225 | raise ValueError('Expected a symbolic Tensor for the metric value, ' |
| 1226 | 'received: ' + str(value)) |
| 1227 | |
| 1228 | # Possible a metric was added in a Layer's `build`. |
| 1229 | if not getattr(self, '_is_graph_network', False): |
| 1230 | with backend.get_graph().as_default(): |