(self)
| 476 | |
| 477 | @set_threefry_partitionable(False) # TODO(yongqiang): update for threefry_partitionable True |
| 478 | def test_forward_summary(self): |
| 479 | input_dim, vocab_size = 16, 20 |
| 480 | cfg: CTCDecoderModel.Config = CTCDecoderModel.default_config().set( |
| 481 | input_dim=input_dim, |
| 482 | vocab_size=vocab_size, |
| 483 | blank_id=0, |
| 484 | ) |
| 485 | # Initialize layer parameters. |
| 486 | layer: CTCDecoderModel = cfg.set(name="test").instantiate(parent=None) |
| 487 | prng_key = jax.random.PRNGKey(123) |
| 488 | prng_key, init_key, input_key, target_key = jax.random.split(prng_key, num=4) |
| 489 | layer_params = layer.initialize_parameters_recursively(init_key) |
| 490 | |
| 491 | batch_size, max_seq_len = 8, 10 |
| 492 | |
| 493 | # Sample indices 2, 3 are invalid, since target_lengths exceeds input_lengths. |
| 494 | input_lengths = jnp.array([10, 5, 7, 0, 6, 3, 8, 1], dtype=jnp.int32) |
| 495 | target_lengths = jnp.array([6, 3, 9, 1, 6, 0, 4, 0], dtype=jnp.int32) |
| 496 | per_example_weight = jnp.array([1, 1, 0, 0, 1, 1, 1, 1], dtype=jnp.float32) |
| 497 | # [batch_size, max_seq_len, dim]. |
| 498 | inputs = jax.random.normal(input_key, [batch_size, max_seq_len, input_dim]) * 1000 |
| 499 | target_labels = jax.random.randint( |
| 500 | target_key, [batch_size, max_seq_len], minval=0, maxval=vocab_size |
| 501 | ) |
| 502 | # [batch_size, max_seq_len]. |
| 503 | paddings = jnp.arange(max_seq_len) >= input_lengths[:, None] |
| 504 | # Map padding targets out-of-vocab. |
| 505 | target_labels = jnp.where( |
| 506 | jnp.arange(max_seq_len) >= target_lengths[:, None], -1, target_labels |
| 507 | ) |
| 508 | target_paddings = target_labels == -1 |
| 509 | input_batch = dict(inputs=inputs, paddings=paddings, target_labels=target_labels) |
| 510 | _, output_collections = F( |
| 511 | layer, |
| 512 | inputs=dict(input_batch=input_batch), |
| 513 | is_training=True, |
| 514 | prng_key=prng_key, |
| 515 | state=layer_params, |
| 516 | ) |
| 517 | summaries = output_collections.summaries |
| 518 | # 6 out of 8 examples are valid, therefore the average example weight is 0.75 |
| 519 | self._check_summary(summaries, "loss/example_weight", WeightedSummary(0.75, 8)) |
| 520 | self._check_summary(summaries, "loss/ctc_loss", WeightedSummary(6972.135, 6)) |
| 521 | self._check_summary(summaries, "loss/invalid_seq_percent", 0.25) |
| 522 | total_ctc_loss = summaries["loss/ctc_loss"].weight * summaries["loss/ctc_loss"].mean |
| 523 | num_valid_frames = jnp.sum(safe_not(paddings) * per_example_weight[:, None]) |
| 524 | num_valid_labels = jnp.sum(safe_not(target_paddings) * per_example_weight[:, None]) |
| 525 | num_valid_examples = jnp.sum(per_example_weight) |
| 526 | self._check_summary( |
| 527 | summaries, |
| 528 | "loss/per_frame_ctc_loss", |
| 529 | WeightedSummary(total_ctc_loss / num_valid_frames, num_valid_frames), |
| 530 | ) |
| 531 | self._check_summary( |
| 532 | summaries, |
| 533 | "loss/per_label_ctc_loss", |
| 534 | WeightedSummary(total_ctc_loss / num_valid_labels, num_valid_labels), |
| 535 | ) |
nothing calls this directly
no test coverage detected