dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
234 lines
8.9 KiB
Python
234 lines
8.9 KiB
Python
"""Tests for CRF."""
|
|
|
|
# original code taken from
|
|
# https://github.com/tensorflow/addons/blob/master/tensorflow_addons/text/tests/crf_test.py
|
|
# (modified to our neeeds)
|
|
|
|
import itertools
|
|
|
|
import pytest
|
|
import numpy as np
|
|
import tensorflow as tf
|
|
|
|
from rasa.utils.tensorflow.crf import (
|
|
crf_sequence_score,
|
|
crf_unary_score,
|
|
crf_binary_score,
|
|
crf_log_norm,
|
|
crf_log_likelihood,
|
|
)
|
|
|
|
|
|
def calculate_sequence_score(inputs, transition_params, tag_indices, sequence_lengths):
|
|
expected_unary_score = sum(
|
|
inputs[i][tag_indices[i]] for i in range(sequence_lengths)
|
|
)
|
|
expected_binary_score = sum(
|
|
transition_params[tag_indices[i], tag_indices[i + 1]]
|
|
for i in range(sequence_lengths - 1)
|
|
)
|
|
return expected_unary_score + expected_binary_score
|
|
|
|
|
|
def brute_force_decode(sequence_lengths, inputs, transition_params):
|
|
num_words = inputs.shape[0]
|
|
num_tags = inputs.shape[1]
|
|
|
|
all_sequence_scores = []
|
|
all_sequences = []
|
|
|
|
tag_indices_iterator = itertools.product(range(num_tags), repeat=sequence_lengths)
|
|
inputs = tf.expand_dims(inputs, 0)
|
|
sequence_lengths = tf.expand_dims(sequence_lengths, 0)
|
|
transition_params = tf.constant(transition_params)
|
|
|
|
# Compare the dynamic program with brute force computation.
|
|
for tag_indices in tag_indices_iterator:
|
|
tag_indices = list(tag_indices)
|
|
tag_indices.extend([0] * (num_words - sequence_lengths))
|
|
all_sequences.append(tag_indices)
|
|
sequence_score = crf_sequence_score(
|
|
inputs=inputs,
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=sequence_lengths,
|
|
transition_params=transition_params,
|
|
)
|
|
sequence_score = tf.squeeze(sequence_score, [0])
|
|
all_sequence_scores.append(sequence_score)
|
|
|
|
expected_max_sequence_index = np.argmax(all_sequence_scores)
|
|
expected_max_sequence = all_sequences[expected_max_sequence_index]
|
|
expected_max_score = all_sequence_scores[expected_max_sequence_index]
|
|
return expected_max_sequence, expected_max_score
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float16, np.float32])
|
|
def test_crf_sequence_score(dtype):
|
|
transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=dtype)
|
|
# Test both the length-1 and regular cases.
|
|
sequence_lengths_list = [
|
|
np.array(3, dtype=np.int32),
|
|
np.array(1, dtype=np.int32),
|
|
]
|
|
inputs_list = [
|
|
np.array([[4, 5, -3], [3, -1, 3], [-1, 2, 1], [0, 0, 0]], dtype=dtype),
|
|
np.array([[4, 5, -3]], dtype=dtype),
|
|
]
|
|
tag_indices_list = [
|
|
np.array([1, 2, 1, 0], dtype=np.int32),
|
|
np.array([1], dtype=np.int32),
|
|
]
|
|
for sequence_lengths, inputs, tag_indices in zip(
|
|
sequence_lengths_list, inputs_list, tag_indices_list
|
|
):
|
|
sequence_score = crf_sequence_score(
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
transition_params=tf.constant(transition_params),
|
|
)
|
|
sequence_score = tf.squeeze(sequence_score, [0])
|
|
|
|
expected_sequence_score = calculate_sequence_score(
|
|
inputs, transition_params, tag_indices, sequence_lengths
|
|
)
|
|
np.testing.assert_allclose(sequence_score, expected_sequence_score)
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float16, np.float32])
|
|
def test_crf_unary_score(dtype):
|
|
inputs = np.array([[4, 5, -3], [3, -1, 3], [-1, 2, 1], [0, 0, 0]], dtype=dtype)
|
|
for dtype in (np.int32, np.int64):
|
|
tag_indices = np.array([1, 2, 1, 0], dtype=dtype)
|
|
sequence_lengths = np.array(3, dtype=np.int32)
|
|
unary_score = crf_unary_score(
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
)
|
|
unary_score = tf.squeeze(unary_score, [0])
|
|
expected_unary_score = sum(
|
|
inputs[i][tag_indices[i]] for i in range(sequence_lengths)
|
|
)
|
|
np.testing.assert_allclose(unary_score, expected_unary_score)
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float16, np.float32])
|
|
def test_crf_binary_score(dtype):
|
|
tag_indices = np.array([1, 2, 1, 0], dtype=np.int32)
|
|
transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=dtype)
|
|
sequence_lengths = np.array(3, dtype=np.int32)
|
|
binary_score = crf_binary_score(
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
transition_params=tf.constant(transition_params),
|
|
)
|
|
binary_score = tf.squeeze(binary_score, [0])
|
|
expected_binary_score = sum(
|
|
transition_params[tag_indices[i], tag_indices[i + 1]]
|
|
for i in range(sequence_lengths - 1)
|
|
)
|
|
np.testing.assert_allclose(binary_score, expected_binary_score)
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float16, np.float32])
|
|
def test_crf_log_norm(dtype):
|
|
transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=dtype)
|
|
# Test both the length-1 and regular cases.
|
|
sequence_lengths_list = [
|
|
np.array(3, dtype=np.int32),
|
|
np.array(1, dtype=np.int64),
|
|
]
|
|
inputs_list = [
|
|
np.array([[4, 5, -3], [3, -1, 3], [-1, 2, 1], [0, 0, 0]], dtype=dtype),
|
|
np.array([[3, -1, 3]], dtype=dtype),
|
|
]
|
|
tag_indices_list = [
|
|
np.array([1, 2, 1, 0], dtype=np.int32),
|
|
np.array([2], dtype=np.int32),
|
|
]
|
|
|
|
for sequence_lengths, inputs, tag_indices in zip(
|
|
sequence_lengths_list, inputs_list, tag_indices_list
|
|
):
|
|
num_words = inputs.shape[0]
|
|
num_tags = inputs.shape[1]
|
|
all_sequence_scores = []
|
|
|
|
# Compare the dynamic program with brute force computation.
|
|
for tag_indices in itertools.product(range(num_tags), repeat=sequence_lengths):
|
|
tag_indices = list(tag_indices)
|
|
tag_indices.extend([0] * (num_words - sequence_lengths))
|
|
all_sequence_scores.append(
|
|
crf_sequence_score(
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
transition_params=tf.constant(transition_params),
|
|
)
|
|
)
|
|
|
|
brute_force_log_norm = tf.reduce_logsumexp(all_sequence_scores)
|
|
log_norm = crf_log_norm(
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
transition_params=tf.constant(transition_params),
|
|
)
|
|
log_norm = tf.squeeze(log_norm, [0])
|
|
|
|
np.testing.assert_allclose(log_norm, brute_force_log_norm)
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float16, np.float32])
|
|
def test_crf_log_norm_zero_seq_length(dtype):
|
|
"""Test `crf_log_norm` when `sequence_lengths` contains one or more
|
|
zeros."""
|
|
inputs = tf.constant(np.ones([2, 10, 5], dtype=dtype))
|
|
transition_params = tf.constant(np.ones([5, 5], dtype=dtype))
|
|
sequence_lengths = tf.constant(np.zeros([2], dtype=np.int32))
|
|
expected_log_norm = np.zeros([2], dtype=dtype)
|
|
log_norm = crf_log_norm(inputs, sequence_lengths, transition_params)
|
|
np.testing.assert_allclose(log_norm, expected_log_norm)
|
|
|
|
|
|
@pytest.mark.parametrize("dtype", [np.float32])
|
|
def test_crf_log_likelihood(dtype):
|
|
inputs = np.array([[4, 5, -3], [3, -1, 3], [-1, 2, 1], [0, 0, 0]], dtype=dtype)
|
|
transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=dtype)
|
|
sequence_lengths = np.array(3, dtype=np.int32)
|
|
|
|
num_words = inputs.shape[0]
|
|
num_tags = inputs.shape[1]
|
|
all_sequence_log_likelihoods = []
|
|
|
|
# Make sure all probabilities sum to 1.
|
|
for tag_indices in itertools.product(range(num_tags), repeat=sequence_lengths):
|
|
tag_indices = list(tag_indices)
|
|
tag_indices.extend([0] * (num_words - sequence_lengths))
|
|
sequence_log_likelihood, _ = crf_log_likelihood(
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
transition_params=tf.constant(transition_params),
|
|
)
|
|
all_sequence_log_likelihoods.append(sequence_log_likelihood)
|
|
total_log_likelihood = tf.reduce_logsumexp(all_sequence_log_likelihoods)
|
|
np.testing.assert_allclose(total_log_likelihood, 0.0, rtol=1e-6, atol=1e-6)
|
|
|
|
# check if `transition_params = None` raises an error
|
|
crf_log_likelihood(
|
|
inputs=tf.expand_dims(inputs, 0),
|
|
tag_indices=tf.expand_dims(tag_indices, 0),
|
|
sequence_lengths=tf.expand_dims(sequence_lengths, 0),
|
|
)
|
|
|
|
|
|
def test_different_dtype():
|
|
inputs = np.ones([16, 20, 5], dtype=np.float32)
|
|
tags = tf.convert_to_tensor(np.ones([16, 20], dtype=np.int64))
|
|
seq_lens = np.ones([16], dtype=np.int64) * 20
|
|
|
|
loss, _ = crf_log_likelihood(
|
|
inputs=inputs, tag_indices=tags, sequence_lengths=seq_lens
|
|
)
|