reader_ops_test.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # Copyright 2016 Google Inc. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """Tests for reader_ops."""
  16. import os.path
  17. import numpy as np
  18. import tensorflow as tf
  19. from tensorflow.python.framework import test_util
  20. from tensorflow.python.platform import googletest
  21. from tensorflow.python.platform import tf_logging as logging
  22. from syntaxnet import dictionary_pb2
  23. from syntaxnet import graph_builder
  24. from syntaxnet import sparse_pb2
  25. from syntaxnet.ops import gen_parser_ops
  26. FLAGS = tf.app.flags.FLAGS
  27. if not hasattr(FLAGS, 'test_srcdir'):
  28. FLAGS.test_srcdir = ''
  29. if not hasattr(FLAGS, 'test_tmpdir'):
  30. FLAGS.test_tmpdir = tf.test.get_temp_dir()
  31. class ParsingReaderOpsTest(test_util.TensorFlowTestCase):
  32. def setUp(self):
  33. # Creates a task context with the correct testing paths.
  34. initial_task_context = os.path.join(
  35. FLAGS.test_srcdir,
  36. 'syntaxnet/'
  37. 'testdata/context.pbtxt')
  38. self._task_context = os.path.join(FLAGS.test_tmpdir, 'context.pbtxt')
  39. with open(initial_task_context, 'r') as fin:
  40. with open(self._task_context, 'w') as fout:
  41. fout.write(fin.read().replace('SRCDIR', FLAGS.test_srcdir)
  42. .replace('OUTPATH', FLAGS.test_tmpdir))
  43. # Creates necessary term maps.
  44. with self.test_session() as sess:
  45. gen_parser_ops.lexicon_builder(task_context=self._task_context,
  46. corpus_name='training-corpus').run()
  47. self._num_features, self._num_feature_ids, _, self._num_actions = (
  48. sess.run(gen_parser_ops.feature_size(task_context=self._task_context,
  49. arg_prefix='brain_parser')))
  50. def GetMaxId(self, sparse_features):
  51. max_id = 0
  52. for x in sparse_features:
  53. for y in x:
  54. f = sparse_pb2.SparseFeatures()
  55. f.ParseFromString(y)
  56. for i in f.id:
  57. max_id = max(i, max_id)
  58. return max_id
  59. def testParsingReaderOp(self):
  60. # Runs the reader over the test input for two epochs.
  61. num_steps_a = 0
  62. num_actions = 0
  63. num_word_ids = 0
  64. num_tag_ids = 0
  65. num_label_ids = 0
  66. batch_size = 10
  67. with self.test_session() as sess:
  68. (words, tags, labels), epochs, gold_actions = (
  69. gen_parser_ops.gold_parse_reader(self._task_context,
  70. 3,
  71. batch_size,
  72. corpus_name='training-corpus'))
  73. while True:
  74. tf_gold_actions, tf_epochs, tf_words, tf_tags, tf_labels = (
  75. sess.run([gold_actions, epochs, words, tags, labels]))
  76. num_steps_a += 1
  77. num_actions = max(num_actions, max(tf_gold_actions) + 1)
  78. num_word_ids = max(num_word_ids, self.GetMaxId(tf_words) + 1)
  79. num_tag_ids = max(num_tag_ids, self.GetMaxId(tf_tags) + 1)
  80. num_label_ids = max(num_label_ids, self.GetMaxId(tf_labels) + 1)
  81. self.assertIn(tf_epochs, [0, 1, 2])
  82. if tf_epochs > 1:
  83. break
  84. # Runs the reader again, this time with a lot of added graph nodes.
  85. num_steps_b = 0
  86. with self.test_session() as sess:
  87. num_features = [6, 6, 4]
  88. num_feature_ids = [num_word_ids, num_tag_ids, num_label_ids]
  89. embedding_sizes = [8, 8, 8]
  90. hidden_layer_sizes = [32, 32]
  91. # Here we aim to test the iteration of the reader op in a complex network,
  92. # not the GraphBuilder.
  93. parser = graph_builder.GreedyParser(
  94. num_actions, num_features, num_feature_ids, embedding_sizes,
  95. hidden_layer_sizes)
  96. parser.AddTraining(self._task_context,
  97. batch_size,
  98. corpus_name='training-corpus')
  99. sess.run(parser.inits.values())
  100. while True:
  101. tf_epochs, tf_cost, _ = sess.run(
  102. [parser.training['epochs'], parser.training['cost'],
  103. parser.training['train_op']])
  104. num_steps_b += 1
  105. self.assertGreaterEqual(tf_cost, 0)
  106. self.assertIn(tf_epochs, [0, 1, 2])
  107. if tf_epochs > 1:
  108. break
  109. # Assert that the two runs made the exact same number of steps.
  110. logging.info('Number of steps in the two runs: %d, %d',
  111. num_steps_a, num_steps_b)
  112. self.assertEqual(num_steps_a, num_steps_b)
  113. def testParsingReaderOpWhileLoop(self):
  114. feature_size = 3
  115. batch_size = 5
  116. def ParserEndpoints():
  117. return gen_parser_ops.gold_parse_reader(self._task_context,
  118. feature_size,
  119. batch_size,
  120. corpus_name='training-corpus')
  121. with self.test_session() as sess:
  122. # The 'condition' and 'body' functions expect as many arguments as there
  123. # are loop variables. 'condition' depends on the 'epoch' loop variable
  124. # only, so we disregard the remaining unused function arguments. 'body'
  125. # returns a list of updated loop variables.
  126. def Condition(epoch, *unused_args):
  127. return tf.less(epoch, 2)
  128. def Body(epoch, num_actions, *feature_args):
  129. # By adding one of the outputs of the reader op ('epoch') as a control
  130. # dependency to the reader op we force the repeated evaluation of the
  131. # reader op.
  132. with epoch.graph.control_dependencies([epoch]):
  133. features, epoch, gold_actions = ParserEndpoints()
  134. num_actions = tf.maximum(num_actions,
  135. tf.reduce_max(gold_actions, [0], False) + 1)
  136. feature_ids = []
  137. for i in range(len(feature_args)):
  138. feature_ids.append(features[i])
  139. return [epoch, num_actions] + feature_ids
  140. epoch = ParserEndpoints()[-2]
  141. num_actions = tf.constant(0)
  142. loop_vars = [epoch, num_actions]
  143. res = sess.run(
  144. tf.while_loop(Condition, Body, loop_vars,
  145. shape_invariants=[tf.TensorShape(None)] * 2,
  146. parallel_iterations=1))
  147. logging.info('Result: %s', res)
  148. self.assertEqual(res[0], 2)
  149. def testWordEmbeddingInitializer(self):
  150. def _TokenEmbedding(token, embedding):
  151. e = dictionary_pb2.TokenEmbedding()
  152. e.token = token
  153. e.vector.values.extend(embedding)
  154. return e.SerializeToString()
  155. # Provide embeddings for the first three words in the word map.
  156. records_path = os.path.join(FLAGS.test_tmpdir, 'sstable-00000-of-00001')
  157. writer = tf.python_io.TFRecordWriter(records_path)
  158. writer.write(_TokenEmbedding('.', [1, 2]))
  159. writer.write(_TokenEmbedding(',', [3, 4]))
  160. writer.write(_TokenEmbedding('the', [5, 6]))
  161. del writer
  162. with self.test_session():
  163. embeddings = gen_parser_ops.word_embedding_initializer(
  164. vectors=records_path,
  165. task_context=self._task_context).eval()
  166. self.assertAllClose(
  167. np.array([[1. / (1 + 4) ** .5, 2. / (1 + 4) ** .5],
  168. [3. / (9 + 16) ** .5, 4. / (9 + 16) ** .5],
  169. [5. / (25 + 36) ** .5, 6. / (25 + 36) ** .5]]),
  170. embeddings[:3,])
  171. if __name__ == '__main__':
  172. googletest.main()