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 = text.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
def testCrfSequenceScore(self): transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=np.float32) # 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=np.float32), np.array([[4, 5, -3]], dtype=np.float32), ] 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 = text.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]) tf_sequence_score = self.evaluate(sequence_score) expected_sequence_score = self.calculateSequenceScore( inputs, transition_params, tag_indices, sequence_lengths) self.assertAllClose(tf_sequence_score, expected_sequence_score)
def test_viterbi_decode(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_scores = [] all_sequences = [] # 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_sequences.append(tag_indices) sequence_score = text.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]) 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] actual_max_sequence, actual_max_score = text.viterbi_decode( inputs[:sequence_lengths], transition_params ) test_utils.assert_allclose_according_to_type(actual_max_score, expected_max_score) assert actual_max_sequence == expected_max_sequence[:sequence_lengths]
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 = text.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 ) test_utils.assert_allclose_according_to_type( sequence_score, expected_sequence_score )
def testCrfDecode(self): transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=np.float32) # 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=np.float32), np.array([[-1, 2, 1]], dtype=np.float32), ] 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 = [] all_sequences = [] # 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_sequences.append(tag_indices) sequence_score = text.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]) all_sequence_scores.append(sequence_score) tf_all_sequence_scores = self.evaluate(all_sequence_scores) expected_max_sequence_index = np.argmax(tf_all_sequence_scores) expected_max_sequence = all_sequences[expected_max_sequence_index] expected_max_score = tf_all_sequence_scores[ expected_max_sequence_index] actual_max_sequence, actual_max_score = text.crf_decode( tf.expand_dims(inputs, 0), tf.constant(transition_params), tf.expand_dims(sequence_lengths, 0)) actual_max_sequence = tf.squeeze(actual_max_sequence, [0]) actual_max_score = tf.squeeze(actual_max_score, [0]) tf_actual_max_sequence, tf_actual_max_score = self.evaluate( [actual_max_sequence, actual_max_score]) self.assertAllClose(tf_actual_max_score, expected_max_score) self.assertEqual( list(tf_actual_max_sequence[:sequence_lengths]), expected_max_sequence[:sequence_lengths])
def testCrfLogNorm(self): transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=np.float32) # 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=np.float32), np.array([[3, -1, 3]], dtype=np.float32), ] 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( text.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 = text.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]) tf_brute_force_log_norm, tf_log_norm = self.evaluate( [brute_force_log_norm, log_norm]) self.assertAllClose(tf_log_norm, tf_brute_force_log_norm)
def testViterbiDecode(self): inputs = np.array([[4, 5, -3], [3, -1, 3], [-1, 2, 1], [0, 0, 0]], dtype=np.float32) transition_params = np.array([[-3, 5, -2], [3, 4, 1], [1, 2, 1]], dtype=np.float32) sequence_lengths = np.array(3, dtype=np.int32) # TODO: https://github.com/PyCQA/pylint/issues/3139 # pylint: disable=E1136 num_words = inputs.shape[0] num_tags = inputs.shape[1] # pylint: enable=E1136 all_sequence_scores = [] all_sequences = [] # 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_sequences.append(tag_indices) sequence_score = text.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]) all_sequence_scores.append(sequence_score) tf_all_sequence_scores = self.evaluate(all_sequence_scores) expected_max_sequence_index = np.argmax(tf_all_sequence_scores) expected_max_sequence = all_sequences[expected_max_sequence_index] expected_max_score = tf_all_sequence_scores[ expected_max_sequence_index] actual_max_sequence, actual_max_score = text.viterbi_decode( inputs[:sequence_lengths], transition_params) self.assertAllClose(actual_max_score, expected_max_score) self.assertEqual(actual_max_sequence, expected_max_sequence[:sequence_lengths])