def test_rnn_with_cells(self): gru_cell1 = tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=16), 'gru1') gru_cell2 = tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=16), 'gru2') with tf.variable_scope('gru3') as vscope: gru_cell3 = tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=16), vscope) lstm_cell = tdl.ScopedLayer( tf.contrib.rnn.BasicLSTMCell(num_units=16), 'lstm') gru1 = (tdb.InputTransform(lambda s: [ord(c) for c in s]) >> tdb.Map(tdb.Scalar('int32') >> tdb.Function(tdl.Embedding(128, 8))) >> tdb.RNN(gru_cell1)) gru2 = (tdb.InputTransform(lambda s: [ord(c) for c in s]) >> tdb.Map(tdb.Scalar('int32') >> tdb.Function(tdl.Embedding(128, 8))) >> tdb.RNN(gru_cell2, initial_state=tf.ones(16))) gru3 = (tdb.InputTransform(lambda s: [ord(c) for c in s]) >> tdb.Map(tdb.Scalar('int32') >> tdb.Function(tdl.Embedding(128, 8))) >> tdb.RNN(gru_cell3, initial_state=tdb.FromTensor(tf.ones(16)))) lstm = (tdb.InputTransform(lambda s: [ord(c) for c in s]) >> tdb.Map(tdb.Scalar('int32') >> tdb.Function(tdl.Embedding(128, 8))) >> tdb.RNN(lstm_cell)) with self.test_session(): gru1.eval('abcde') gru2.eval('ABCDE') gru3.eval('vghj') lstm.eval('123abc')
def test_length(self): scalar_then_length = tdb.Map(tdb.Scalar('int32')) >> tdb.Length() scalar_then_int_length = ( tdb.Map(tdb.Scalar(dtype='float64')) >> tdb.Length(dtype='int64')) self.assertBuilds(3.0, scalar_then_length, [1, 2, 3], max_depth=0) self.assertBuilds(10.0, scalar_then_length, range(10), max_depth=0) self.assertBuilds(3, scalar_then_int_length, [1, 2, 3], max_depth=0)
def test_slice_sequence(self): self.assertBuildsConst( [0., 1., 2.], tdb.Map(tdb.Scalar()) >> tdb.Slice(), range(3)) self.assertBuildsConst( [0., 1.], tdb.Map(tdb.Scalar()) >> tdb.Slice(stop=2), range(3)) self.assertBuildsConst( [2., 1., 0.], tdb.Map(tdb.Scalar()) >> tdb.Slice(step=-1), range(3))
def test_nth_raises(self): six.assertRaisesRegex( self, TypeError, 'Nth block takes 2 inputs', tdb.Pipe, (tdb.Scalar(), tdb.Scalar(), tdb.Scalar()), tdb.Nth()) six.assertRaisesRegex( self, TypeError, 'first input to Nth must be a sequence', tdb.Pipe, (tdb.Scalar(), tdb.Scalar()), tdb.Nth()) six.assertRaisesRegex( self, TypeError, 'second input to Nth must be a PyObject', tdb.Pipe, (tdb.Map(tdb.Scalar()), tdb.Map(tdb.Scalar())), tdb.Nth())
def test_hierarchical_rnn(self): char_cell = tdl.ScopedLayer( tf.contrib.rnn.BasicLSTMCell(num_units=16), 'char_cell') word_cell = tdl.ScopedLayer( tf.contrib.rnn.BasicLSTMCell(num_units=32), 'word_cell') char_lstm = (tdb.InputTransform(lambda s: [ord(c) for c in s]) >> tdb.Map(tdb.Scalar('int32') >> tdb.Function(tdl.Embedding(128, 8))) >> tdb.RNN(char_cell)) word_lstm = (tdb.Map(char_lstm >> tdb.GetItem(1) >> tdb.Concat()) >> tdb.RNN(word_cell)) with self.test_session(): word_lstm.eval(['the', 'cat', 'sat', 'on', 'a', 'mat'])
def test_metrics_scalar(self): block = tdb.Map(_pos_neg_block([])) >> tdb.Sum() with self.test_session() as sess: compiler = tdc.Compiler.create(block) sess.run(tf.global_variables_initializer()) fd = compiler.build_feed_dict([[1, 2, 3, 4]]) self.assertSameStructure( [10.], sess.run(compiler.output_tensors[0], fd).tolist()) positive = compiler.metric_tensors['positive'] negative = compiler.metric_tensors['negative'] fd = compiler.build_feed_dict([[1, -2, 3, -4, 5, -6]]) pos, neg = sess.run([positive, negative], fd) np.testing.assert_equal(pos, [1, 3, 5]) np.testing.assert_equal(neg, [-2, -4, -6]) fd = compiler.build_feed_dict([[-1, -2, 3, -4, -5, -6]]) pos, neg = sess.run([positive, negative], fd) np.testing.assert_equal(pos, [3]) # test single value np.testing.assert_equal(neg, [-1, -2, -4, -5, -6]) fd = compiler.build_feed_dict([[1, 2, 3, 4, 5, 6]]) pos, neg = sess.run([positive, negative], fd) np.testing.assert_equal(pos, [1, 2, 3, 4, 5, 6]) np.testing.assert_equal(neg, []) # test no values # test batches fd = compiler.build_feed_dict([[1, 2, -3, -4], [5, 6, -7, -8, 0]]) pos, neg = sess.run([positive, negative], fd) np.testing.assert_equal(pos, [1, 2, 5, 6]) np.testing.assert_equal(neg, [-3, -4, -7, -8, 0])
def test_mean_matrix(self): to_2_by_3_matrix = tdb.Tensor(shape=[2, 3], name='2by3Matrix') mean_matrix = tdb.Map(to_2_by_3_matrix) >> tdb.Mean() six_range = np.reshape(range(6), (2, 3)) self.assertBuilds([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], mean_matrix, [six_range+1.0, six_range, six_range+2.0], max_depth=3)
def test_reduce_default_zero(self): sum_or_ten = (tdb.Map(tdb.Scalar()) >> tdb.Reduce(tdb.Function(tf.add))) self.assertBuilds(0.0, sum_or_ten, [], max_depth=0) self.assertBuilds(3.0, sum_or_ten, [1.0, 2.0], max_depth=1) self.assertBuilds(20.0, sum_or_ten, [2.0, 4.0, 6.0, 8.0], max_depth=2) self.assertBuilds(6.0, sum_or_ten, [1.0, 2.0, 3.0], max_depth=2) self.assertBuilds(21.0, sum_or_ten, range(7), max_depth=3)
def test_max_depth_metrics(self): elem_block = tdb.Composition() with elem_block.scope(): s = tdb.Scalar('int32').reads(elem_block.input) tdm.Metric('foo').reads(s) elem_block.output.reads(s) block = (tdb.Map(elem_block), tdb.Identity()) >> tdb.Nth() self.assertBuilds((31, {'foo': list(xrange(32))}), block, (range(32), -1))
def test_fold(self): const_ten = np.array(10.0, dtype='float32') ten_plus_sum = (tdb.Map(tdb.Scalar()) >> tdb.Fold(tdb.Function(tf.add), const_ten)) self.assertBuilds(16.0, ten_plus_sum, [1.0, 2.0, 3.0], max_depth=3) self.assertBuilds(16.0, ten_plus_sum, [3.0, 2.0, 1.0], max_depth=3) self.assertBuilds(20.0, ten_plus_sum, [1.0, 2.0, 3.0, 4.0], max_depth=4) self.assertBuilds(20.0, ten_plus_sum, [4.0, 3.0, 2.0, 1.0], max_depth=4)
def test_forward_declaration_orphaned_nested(self): fwd1 = tdb.ForwardDeclaration(tdt.VoidType(), tdt.TensorType([])) fwd2 = tdb.ForwardDeclaration(tdt.SequenceType(tdt.TensorType([])), tdt.TensorType([])) b = tdb.Map(tdb.Scalar()) >> fwd2() >> tdb.Function(tf.negative) fwd2.resolve_to(tdb.Fold(tdb.Function(tf.add), fwd1())) fwd1.resolve_to(tdb.FromTensor(tf.ones([]))) self.assertBuilds(-8., b, [3, 4], max_depth=3)
def test_reduce(self): const_ten = np.array(10.0, dtype='float32') sum_or_ten = (tdb.Map(tdb.Scalar()) >> tdb.Reduce(tdb.Function(tf.add), const_ten)) self.assertBuilds(10.0, sum_or_ten, [], max_depth=0) self.assertBuilds(3.0, sum_or_ten, [1.0, 2.0], max_depth=1) self.assertBuilds(20.0, sum_or_ten, [2.0, 4.0, 6.0, 8.0], max_depth=2) self.assertBuilds(6.0, sum_or_ten, [1.0, 2.0, 3.0], max_depth=2) self.assertBuilds(21.0, sum_or_ten, range(7), max_depth=3)
def test_init_raises(self): six.assertRaisesRegex(self, TypeError, 'root must have at least one output', tdc.Compiler.create, tdb.Record([])) six.assertRaisesRegex(self, TypeError, 'root outputs must all be tensors', tdc.Compiler.create, tdb.GetItem('foo')) six.assertRaisesRegex(self, TypeError, 'root output may not contain sequences', tdc.Compiler.create, tdb.Map(tdb.Scalar()))
def test_rnn(self): # We have to expand_dims to broadcast x over the batch. def f(x, st): return (tf.multiply(x, x), tf.add(st, tf.expand_dims(x, 1))) intup = (tdb.Map(tdb.Scalar()), tdb.Vector(2)) block = intup >> tdb.RNN(tdb.Function(f), initial_state_from_input=True) self.assertBuilds(([], [0.0, 0.0]), block, ([], [0.0, 0.0]), max_depth=0) self.assertBuilds(([1.0, 4.0, 9.0, 16.0], [10.0, 10.0]), block, ([1.0, 2.0, 3.0, 4.0], [0.0, 0.0]), max_depth=4) self.assertBuilds(([1.0, 4.0, 9.0, 16.0], [10.0, 10.0]), block, ([1.0, 2.0, 3.0, 4.0], [0.0, 0.0]), max_depth=4)
def test_metrics_vector(self): block = tdb.Map(_pos_neg_block([2])) >> tdb.Sum() with self.test_session() as sess: compiler = tdc.Compiler.create(block) sess.run(tf.global_variables_initializer()) positive = compiler.metric_tensors['positive'] negative = compiler.metric_tensors['negative'] fd = compiler.build_feed_dict([[[1, 2], [-2, -3], [4, 5]]]) pos, neg = sess.run([positive, negative], fd) np.testing.assert_equal(pos, [[1, 2], [4, 5]]) np.testing.assert_equal(neg, [[-2, -3]])
def test_metrics_labeled(self): tree1 = [1, 'a', [2, 'b'], [3, 'c'], [4, 'd']] tree2 = [5, 'e', [6, 'f', [7, 'g']]] fwd = tdb.ForwardDeclaration() leaf = (tdb.Scalar('int32'), tdb.Identity()) >> tdm.Metric('leaf') internal = tdb.AllOf( (tdb.Scalar('int32'), tdb.Identity()) >> tdm.Metric('internal'), tdb.Slice(start=2) >> tdb.Map(fwd())) >> tdb.Void() tree = tdb.OneOf(key_fn=lambda expr: len(expr) > 2, case_blocks=(leaf, internal)) fwd.resolve_to(tree) with self.test_session() as sess: c = tdc.Compiler.create(tree) feed_dict, labels = c.build_feed_dict([tree1, tree2], metric_labels=True) self.assertEqual(['b', 'c', 'd', 'g'], labels['leaf']) self.assertEqual(['a', 'e', 'f'], labels['internal']) leaf_values, internal_values = sess.run( [c.metric_tensors['leaf'], c.metric_tensors['internal']], feed_dict) np.testing.assert_equal([2, 3, 4, 7], leaf_values) np.testing.assert_equal([1, 5, 6], internal_values)
def test_max_depth(self): self.assertEqual(0, tdb.Scalar().max_depth(42)) block = (tdb.Map(tdb.Scalar()) >> tdb.Fold(tdb.Function(tf.add), tf.zeros([]))) for i in xrange(5): self.assertEqual(i, block.max_depth(range(i)))
def test_tuple_of_seq(self): block = tdb.AllOf( tdb.Map(tdb.Scalar() >> tdb.Function(tf.negative)), tdb.Map(tdb.Scalar() >> tdb.Function(tf.identity))) self.assertBuilds(([], []), block, [], max_depth=0) self.assertBuilds(([-1., -2.], [1., 2.]), block, [1, 2])
def test_nth(self): block = (tdb.Map(tdb.Scalar('int32')), tdb.Identity()) >> tdb.Nth() for n in xrange(5): self.assertBuildsConst(n, block, (range(5), n))
def test_ngrams_2(self): block = tdb.Map(tdb.Scalar()) >> tdb.NGrams(2) self.assertBuildsConst([], block, []) self.assertBuildsConst([], block, [1.]) self.assertBuildsConst([(1., 2.)], block, [1, 2]) self.assertBuildsConst([(1., 2.), (2., 3.)], block, [1, 2, 3])
def test_ngrams_1(self): block = tdb.Map(tdb.Scalar()) >> tdb.NGrams(1) self.assertBuildsConst([], block, []) self.assertBuildsConst([(1.,)], block, [1]) self.assertBuildsConst([(1.,), (2.,)], block, [1, 2])
def test_input_transform_const(self): block = tdb.Map(tdb.InputTransform(lambda x: 1 + ord(x) - ord('a')) >> tdb.Scalar('int32')) self.assertBuildsConst([1, 2, 3, 4], block, 'abcd')
def test_broadcast_zip_map(self): block = ({'x': tdb.Scalar() >> tdb.Broadcast(), 'y': tdb.Map(tdb.Scalar())} >> tdb.Zip() >> tdb.Map(tdb.Function(tf.add))) self.assertBuilds([3., 4., 5.], block, {'x': 2, 'y': [1, 2, 3]})
def test_zip_some_broadcast(self): block = {'x': tdb.Map(tdb.Scalar()), 'y': tdb.Scalar() >> tdb.Broadcast()} >> tdb.Zip() self.assertBuildsConst([(1., 3.), (2., 3.)], block, {'x': [1, 2], 'y': 3})
def test_zip(self): block = {'x': tdb.Map(tdb.Scalar()), 'y': tdb.Map(tdb.Scalar())} >> tdb.Zip() self.assertBuildsConst([(1., 3.)], block, {'x': [1, 2], 'y': [3]})
def test_broadcast_map(self): block = tdb.Scalar() >> tdb.Broadcast() >> tdb.Map( tdb.Function(tf.negative)) self.assertBuilds(itertools.repeat(-42.), block, 42)
def test_optional_default_none(self): block = tdb.Optional({'a': tdb.Map({'b': tdb.Scalar(), 'c': tdb.Scalar()}), 'd': tdb.Vector(3)}) self.assertBuildsConst(([(0., 1.)], [2., 3., 4.]), block, {'a': [{'b': 0, 'c': 1}], 'd': [2, 3, 4]}) self.assertBuildsConst(([], [0., 0., 0.]), block, None)
def test_input_transform(self): block = tdb.Map(tdb.InputTransform(lambda x: 1 + ord(x) - ord('a')) >> tdb.Scalar('int32') >> tdb.Function(tf.negative)) self.assertBuilds([-1, -2, -3, -4], block, 'abcd')
def test_zip_with(self): block = ((tdb.Map(tdb.Scalar()), tdb.Map(tdb.Scalar())) >> tdb.ZipWith(tdb.Function(tf.add))) self.assertBuilds([5., 7., 9.], block, ([1, 2, 3], [4, 5, 6]))
def test_get_item_sequence(self): block = tdb.Map(tdb.Scalar()) >> tdb.GetItem(-1) self.assertBuildsConst(9., block, range(10))