Run evaluation.
(sp_processor, features_map_fn, labels_map_fn, logits_fn,
decode_logits_fn, split_and_pad_fn, distribute_strategy,
validation_dataset, ground_truth)
| 230 | |
| 231 | |
| 232 | def evaluate(sp_processor, features_map_fn, labels_map_fn, logits_fn, |
| 233 | decode_logits_fn, split_and_pad_fn, distribute_strategy, |
| 234 | validation_dataset, ground_truth): |
| 235 | """Run evaluation.""" |
| 236 | loss_metric = tf_keras.metrics.Mean() |
| 237 | |
| 238 | @tf.function |
| 239 | def update_loss(y, logits): |
| 240 | loss_fn = modeling.SpanOrCrossEntropyLoss( |
| 241 | reduction=tf_keras.losses.Reduction.NONE) |
| 242 | return loss_metric(loss_fn(y, logits)) |
| 243 | |
| 244 | predictions = collections.defaultdict(list) |
| 245 | for _, (features, labels) in validation_dataset.enumerate(): |
| 246 | token_ids = features['token_ids'] |
| 247 | y = labels_map_fn(token_ids, labels) |
| 248 | x = split_and_pad_fn(features_map_fn(features)) |
| 249 | logits = tf.concat( |
| 250 | distribute_strategy.experimental_local_results(logits_fn(x)), 0) |
| 251 | logits = logits[:features['token_ids'].shape[0]] |
| 252 | update_loss(y, logits) |
| 253 | end_limit = token_ids.row_lengths() - 1 # inclusive |
| 254 | begin, end, scores = decode_logits_fn(logits, end_limit) |
| 255 | answers = prediction.decode_answer(features['context'], begin, end, |
| 256 | features['token_offsets'], |
| 257 | end_limit).numpy() |
| 258 | for _, (qid, token_id, offset, score, answer) in enumerate( |
| 259 | zip(features['qid'].numpy(), |
| 260 | tf.gather(features['token_ids'], begin, batch_dims=1).numpy(), |
| 261 | tf.gather(features['token_offsets'], begin, batch_dims=1).numpy(), |
| 262 | scores, answers)): |
| 263 | if not answer: |
| 264 | continue |
| 265 | if sp_processor.IdToPiece(int(token_id)).startswith('▁') and offset > 0: |
| 266 | answer = answer[1:] |
| 267 | predictions[qid.decode('utf-8')].append((score, answer.decode('utf-8'))) |
| 268 | predictions = { |
| 269 | qid: evaluation.normalize_answer( |
| 270 | sorted(answers, key=operator.itemgetter(0), reverse=True)[0][1]) |
| 271 | for qid, answers in predictions.items() |
| 272 | } |
| 273 | metrics = evaluation.evaluate_triviaqa(ground_truth, predictions, mute=True) |
| 274 | metrics['loss'] = loss_metric.result().numpy() |
| 275 | return metrics |
| 276 | |
| 277 | |
| 278 | def main(argv): |
nothing calls this directly
no test coverage detected