def test_single_input_sequence_with_implicit_lengths(self): use_log_space = True use_start_and_end_states = False scores = np.array([[10.0, 13.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0], [13.0, 12.0, 11.0, 10.0]]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_weights = np.array( [[-1.0, 1.0, -2.0, 2.0], [3.0, -3.0, 4.0, -4.0], [5.0, 1.0, 10.0, 1.0], [-7.0, 7.0, -8.0, 8.0]], dtype=np.float32) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation sequence, _ = viterbi_decode.decode( scores, transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) # Test a multi-item batch. multiple_input = np.array([scores], dtype=np.float32) single_sequence_op = sequence_op.viterbi_constrained_sequence( multiple_input, transition_weights=transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) single_sequence_result = self.evaluate(single_sequence_op) self.assertRaggedEqual(single_sequence_result, [sequence])
def test_ragged_input_sequence(self): use_log_space = True use_start_and_end_states = False input_1 = np.array([[10.0, 13.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0], [13.0, 12.0, 11.0, 10.0]]) input_2 = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) # TODO(b/122968457): Extend RT support to lists-of-ndarrays. scores = ragged_factory_ops.constant( [input_1.tolist(), input_2.tolist()]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_weights = np.array( [[-1.0, 1.0, -2.0, 2.0], [3.0, -3.0, 4.0, -4.0], [5.0, 1.0, 10.0, 1.0], [-7.0, 7.0, -8.0, 8.0]], dtype=np.float32) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation sequence_1, _ = viterbi_decode.decode( input_1, transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) sequence_2, _ = viterbi_decode.decode( input_2, transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) expected_sequence = ragged_factory_ops.constant( [sequence_1, sequence_2]) # Test a ragged batch single_sequence_op = sequence_op.viterbi_constrained_sequence( scores, transition_weights=transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) single_sequence_result = self.evaluate(single_sequence_op) self.assertRaggedEqual(single_sequence_result, expected_sequence)
def test_viterbi_in_exp_space_with_negative_weights_fails(self): scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) x = 0.0 # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[.1, .2, .3, .4], [.5, -.6, .7, .8], [.9, x, .15, x], [.25, .35, .45, .55]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation with self.assertRaises(ValueError): _, _ = viterbi_decode.decode(scores, transition_params, use_log_space=False)
def test_viterbi_in_log_space_with_start_and_end(self): scores = np.array([[10.0, 12.0, 7.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) x = -float('inf') # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[-1.0, 1.0, -2.0, 2.0, 0.0], [3.0, -3.0, 4.0, -4.0, 0.0], [5.0, x, 10.0, x, x], [-7.0, 7.0, -8.0, 8.0, 0.0], [0.0, x, 2.0, 3.0, 0.0]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation # STEP 1: # All scores should be summed with the last row in the weight tensor, so the # 'real' scores are: # B0: { 10.0, X, 9.0, 7.0} # # STEP 2: # Raw scores are: {13.0, 12.0, 11.0, 10.0} # # Final state 0: (13.0) Weighted scores are {12.0, 16.0, 18.0, 6.0} # New totals are {22, X, 27, 18} [max 27 from 2] # # Final state 1: (12.0) Weighted scores are {13.0, 9.0, X, 19.0}, # New totals are {23, X, X, 26} [max 26 from 3] # # Final state 2: (11.0) Weighted scores are {9, 15, 21, 3}, # New totals are {19, X, 30, 10} [max 30 from 2] # # Final state 3: (10.0) Weighted scores are {12, 6, X, 18}, # New totals are {19, X, X, 25} [max 25 from 3] # # Top scores are [27, 26, 30, 25] from [2, 3, 2, 3]. # 2->OUT is X, so final scores are [27, 26, X, 25] for a # final state of [0] with a sequence of [2->0]. sequence, score = viterbi_decode.decode(scores, transition_params, use_start_and_end_states=True) self.assertAlmostEqual(27.0, score) self.assertEqual([2, 0], sequence)
def test_viterbi_in_exp_space_with_start_and_end(self): scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) x = 0.0 # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[ .1, .2, .3, .4, .1], [ .5, .6, .7, .8, .1], [ .9, x, .15, x, .1], [.25, .35, .45, .55, .5], [ .1, .5, .1, .1, x]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation # STEP 1: # Starting scores are {.5, 6.0, .6, .4} # Raw scores are: {13.0, 12.0, 11.0, 10.0} # # Final state 0: (13.0) Weighted scores are {1.3, 6.5, 11.7, 3.25} # New totals are {0.13, 39, 7.02, 1.3} [max 39 from 1] # # Final state 1: (12.0) Weighted scores are {2.4, 7.2, 0, 4.2}, # New totals are {0.24, 43.2, 0, 1.68} [max 43.2 from 1] # # Final state 2: (11.0) Weighted scores are {3.3, 7.7, 1.65, 4.95}, # New totals are {0.33, 46.2, 0.99, 1.98} [max 46.2 from 1] # # Final state 3: (10.0) Weighted scores are {4, 8, 0, 5.5}, # New totals are {0.4, 48, 0, 2.2} [max 48 from 1] # # Top scores are [39, 43.2, 46.2, 48] from [1, 1, 1, 1]. # Final multiplication results in [3.9, 4.32, 4.62, 24] # Final state is [3] with a sequence of [1->3]. sequence, score = viterbi_decode.decode( scores, transition_params, use_log_space=False, use_start_and_end_states=True) self.assertAlmostEqual(24.0, score) self.assertEqual([1, 3], sequence)
def test_viterbi_with_allowed_transitions(self): scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[-1.0, 1.0, -2.0, 2.0], [3.0, -3.0, 4.0, -4.0], [5.0, 100.0, 10.0, 200.0], [-7.0, 7.0, -8.0, 8.0]]) allowed_transitions = np.array([[True, True, True, True], [True, True, True, True], [True, False, True, False], [True, True, True, True]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation # STEP 1: # Starting scores are {10.0, 12.0, 6.0, 4.0} # Raw scores are: {13.0, 12.0, 11.0, 10.0} # # Final state 0: (13.0) Weighted scores are {12.0, 16.0, 18.0, 6.0} # New totals are {22, 28, 24, 10} [max 28 from 1] # # Final state 1: (12.0) Weighted scores are {13.0, 9.0, X, 19.0}, # New totals are {23, 21, X, 23} [max 23 from 3] # # Final state 2: (11.0) Weighted scores are {9, 15, 21, 3}, # New totals are {19, 27, 27, 7} [max 27 from 2] # # Final state 3: (10.0) Weighted scores are {12, 6, X, 18}, # New totals are {19, 18, X, 22} [max 22 from 3] # # Top scores are [28, 26, 27, 25] from [1, 3, 2, 3]. # Final state is [0] with a sequence of [1->0]. sequence, score = viterbi_decode.decode(scores, transition_params, allowed_transitions) self.assertAlmostEqual(28.0, score) self.assertEqual([1, 0], sequence)
def test_viterbi_in_exp_space_with_allowed_transitions(self): scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[.1, .2, .3, .4], [.5, .6, .7, .8], [.9, .5, .15, .5], [.25, .35, .45, .55]]) allowed_transitions = np.array([[True, True, True, True], [True, True, True, True], [True, False, True, False], [True, True, True, True]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation # STEP 1: # Starting scores are {10.0, 12.0, 6.0, 4.0} # Raw scores are: {13.0, 12.0, 11.0, 10.0} # # Final state 0: (13.0) Weighted scores are {1.3, 6.5, 11.7, 3.25} # New totals are {13, 78, 70.2, 13} [max 78 from 1] # # Final state 1: (12.0) Weighted scores are {2.4, 7.2, 0, 4.2}, # New totals are {24, 86.4, 0, 16.8} [max 86.4 from 1] # # Final state 2: (11.0) Weighted scores are {3.3, 7.7, 1.65, 4.95}, # New totals are {33, 92.4, 9.9, 19.8} [max 92.4 from 1] # # Final state 3: (10.0) Weighted scores are {4, 8, 0, 5.5}, # New totals are {40, 96, 0, 22} [max 96 from 1] # # Top scores are [78, 86.4, 92.4, 96] from [1, 1, 1, 1]. # Final state is [3] with a sequence of [1->3]. sequence, score = viterbi_decode.decode(scores, transition_params, allowed_transitions, use_log_space=False) self.assertAlmostEqual(96.0, score) self.assertEqual([1, 3], sequence)
def test_sequence_in_log_space_with_start_end_states_multi_input(self): use_log_space = True use_start_and_end_states = True scores = np.array([[10.0, 12.0, 7.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_weights = np.array([[-1.0, 1.0, -2.0, 2.0, 0.0], [ 3.0, -3.0, 4.0, -4.0, 0.0], [ 5.0, 1.0, 10.0, 1.0, 1.0], [-7.0, 7.0, -8.0, 8.0, 0.0], [ 0.0, 1.0, 2.0, 3.0, 0.0]], dtype=np.float32) allowed_transitions = np.array([[True, True, True, True, True], [True, True, True, True, True], [True, False, True, False, False], [True, True, True, True, True], [True, False, True, True, True]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation sequence, _ = viterbi_decode.decode( scores, transition_weights, allowed_transitions, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) # Test a multi-item batch. multiple_input = np.array([scores, scores, scores], dtype=np.float32) multiple_sequence_op = sequence_op.viterbi_constrained_sequence( multiple_input, [2, 2, 2], allowed_transitions=allowed_transitions, transition_weights=transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) multiple_sequence_result = self.evaluate(multiple_sequence_op) self.assertRaggedEqual(multiple_sequence_result, [sequence, sequence, sequence])
def test_sequence_in_exp_space_with_start_end_states_multi_input(self): use_log_space = False use_start_and_end_states = True scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_weights = np.array([[ .1, .2, .3, .4, .1], [ .5, .6, .7, .8, .1], [ .9, 1, .15, 1, .1], [.25, .35, .45, .55, .5], [ .1, .5, .1, .1, 1]], dtype=np.float32) allowed_transitions = np.array([[True, True, True, True, True], [True, True, True, True, True], [True, False, True, False, True], [True, True, True, True, True], [True, True, True, True, False]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation sequence, _ = viterbi_decode.decode( scores, transition_weights, allowed_transitions, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) # Test a multi-item batch. multiple_input = np.array([scores, scores, scores], dtype=np.float32) multiple_sequence_op = sequence_op.viterbi_constrained_sequence( multiple_input, [2, 2, 2], allowed_transitions=allowed_transitions, transition_weights=transition_weights, use_log_space=use_log_space, use_start_and_end_states=use_start_and_end_states) multiple_sequence_result = self.evaluate(multiple_sequence_op) self.assertRaggedEqual(multiple_sequence_result, [sequence, sequence, sequence])
def test_viterbi_in_log_space(self): scores = np.array([[10.0, 12.0, 6.0, 4.0], [13.0, 12.0, 11.0, 10.0]]) x = -float('inf') # pyformat: disable # pylint: disable=bad-whitespace # pylint: disable=bad-continuation transition_params = np.array([[-1.0, 1.0, -2.0, 2.0], [3.0, -3.0, 4.0, -4.0], [5.0, x, 10.0, x], [-7.0, 7.0, -8.0, 8.0]]) # pyformat: enable # pylint: enable=bad-whitespace # pylint: enable=bad-continuation # STEP 1: # Starting scores are {10.0, 12.0, 6.0, 4.0} # Raw scores are: {13.0, 12.0, 11.0, 10.0} # # To get the weighted scores, add the column of the final state to # the raw score. # # Final state 0: (13.0) Weighted scores are {12.0, 16.0, 18.0, 6.0} # New totals are {22, 28, 24, 10} [max 28 from 1] # # Final state 1: (12.0) Weighted scores are {13.0, 9.0, X, 19.0}, # New totals are {23, 21, X, 23} [max 23 from 3] # # Final state 2: (11.0) Weighted scores are {9, 15, 21, 3}, # New totals are {19, 27, 27, 7} [max 27 from 2] # # Final state 3: (10.0) Weighted scores are {12, 6, X, 18}, # New totals are {19, 18, X, 22} [max 25 from 3] # # Top scores are [28, 26, 27, 25] from [1, 3, 2, 3]. # Final state is [0] with a sequence of [1->0]. sequence, score = viterbi_decode.decode(scores, transition_params) self.assertAlmostEqual(28.0, score) self.assertEqual([1, 0], sequence)