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