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_record_composition(self): d = tdb.Record({'a': tdb.Scalar(), 'b': tdb.Scalar()}) fn1 = times_scalar_block(2.0) fn2 = times_scalar_block(3.0) fn3 = tdb.Function(tf.add) c = tdb.Composition([d, fn1, fn2, fn3]) c.connect(c.input, d) c.connect(d['a'], fn1) c.connect(d['b'], fn2) c.connect((fn1, fn2), fn3) c.connect(fn3, c.output) self.assertBuilds(17.0, c, {'a': 1.0, 'b': 5.0}, max_depth=2)
def test_forward_declarations(self): # Define a simple expression data structure nlit = lambda x: {'op': 'lit', 'val': x} nadd = lambda x, y: {'op': 'add', 'left': x, 'right': y} nexpr = nadd(nadd(nlit(3.0), nlit(5.0)), nlit(2.0)) # Define a recursive block using forward declarations expr_fwd = tdb.ForwardDeclaration(tdt.PyObjectType(), tdt.TensorType((), 'float32')) lit_case = tdb.GetItem('val') >> tdb.Scalar() add_case = (tdb.Record({'left': expr_fwd(), 'right': expr_fwd()}) >> tdb.Function(tf.add)) expr = tdb.OneOf(lambda x: x['op'], {'lit': lit_case, 'add': add_case}) expr_fwd.resolve_to(expr) self.assertBuilds(10.0, expr, nexpr, max_depth=2)
def test_eval_empty_tuple(self): block = tdb.Record([]) self.assertBuildsConst((), block, ())
def test_length_empty_tuple(self): block = tdb.Record([]) >> tdb.Length(dtype='int32') self.assertBuildsConst(0, block, ())
def test_record_slice_key(self): b = tdb.Record([ (0, tdb.Scalar()), (slice(1, 3), (tdb.Scalar(), tdb.Scalar()) >> tdb.Concat())]) self.assertBuilds((1., [2., 3.]), b, [1, 2, 3])
def test_record_one_child(self): self.assertBuildsConst((42,), tdb.Record({0: tdb.Scalar('int32')}), {0: 42})
def test_record(self): d = tdb.Record(collections.OrderedDict([('b', tdb.Scalar()), ('a', tdb.Scalar())])) c = d >> tdb.Function(tf.subtract) self.assertBuilds(4.0, c, {'a': 1.0, 'b': 5.0})
def test_repr(self): goldens = { tdb.Tensor([]): '<td.Tensor dtype=\'float32\' shape=()>', tdb.Tensor([1, 2], 'int32', name='foo'): '<td.Tensor \'foo\' dtype=\'int32\' shape=(1, 2)>', tdb.Scalar('int64'): '<td.Scalar dtype=\'int64\'>', tdb.Vector(42): '<td.Vector dtype=\'float32\' size=42>', tdb.FromTensor(tf.zeros(3)): '<td.FromTensor \'zeros:0\'>', tdb.Function(tf.negative, name='foo'): '<td.Function \'foo\' tf_fn=\'negative\'>', tdb.Identity(): '<td.Identity>', tdb.Identity('foo'): '<td.Identity \'foo\'>', tdb.InputTransform(ord): '<td.InputTransform py_fn=\'ord\'>', tdb.SerializedMessageToTree('foo'): '<td.SerializedMessageToTree \'foo\' ' 'py_fn=\'serialized_message_to_tree\'>', tdb.GetItem(3, 'mu'): '<td.GetItem \'mu\' key=3>', tdb.Length(): '<td.Length dtype=\'float32\'>', tdb.Slice(stop=2): '<td.Slice key=slice(None, 2, None)>', tdb.Slice(stop=2, name='x'): '<td.Slice \'x\' key=slice(None, 2, None)>', tdb.ForwardDeclaration(name='foo')(): '<td.ForwardDeclaration() \'foo\'>', tdb.Composition(name='x').input: '<td.Composition.input \'x\'>', tdb.Composition(name='x').output: '<td.Composition.output \'x\'>', tdb.Composition(name='x'): '<td.Composition \'x\'>', tdb.Pipe(): '<td.Pipe>', tdb.Pipe(tdb.Scalar(), tdb.Identity()): '<td.Pipe>', tdb.Record({}, name='x'): '<td.Record \'x\' ordered=False>', tdb.Record((), name='x'): '<td.Record \'x\' ordered=True>', tdb.AllOf(): '<td.AllOf>', tdb.AllOf(tdb.Identity()): '<td.AllOf>', tdb.AllOf(tdb.Identity(), tdb.Identity()): '<td.AllOf>', tdb.AllOf(name='x'): '<td.AllOf \'x\'>', tdb.AllOf(tdb.Identity(), name='x'): '<td.AllOf \'x\'>', tdb.AllOf(tdb.Identity(), tdb.Identity(), name='x'): '<td.AllOf \'x\'>', tdb.Map(tdb.Scalar(), name='x'): '<td.Map \'x\' element_block=<td.Scalar dtype=\'float32\'>>', tdb.Fold(tdb.Function(tf.add), tf.ones([]), name='x'): '<td.Fold \'x\' combine_block=<td.Function tf_fn=\'add\'> ' 'start_block=<td.FromTensor \'ones:0\'>>', tdb.RNN(tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=8))): '<td.RNN>', tdb.RNN(tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=8)), name='x'): '<td.RNN \'x\'>', tdb.RNN(tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=8)), initial_state=tf.ones(8)): '<td.RNN>', tdb.RNN(tdl.ScopedLayer(tf.contrib.rnn.GRUCell(num_units=8)), initial_state=tf.ones(8), name='x'): '<td.RNN \'x\'>', tdb.Reduce(tdb.Function(tf.add), name='x'): '<td.Reduce \'x\' combine_block=<td.Function tf_fn=\'add\'>>', tdb.Sum(name='foo'): '<td.Sum \'foo\' combine_block=<td.Function tf_fn=\'add\'>>', tdb.Min(name='foo'): '<td.Min \'foo\' combine_block=<td.Function tf_fn=\'minimum\'>>', tdb.Max(name='foo'): '<td.Max \'foo\' combine_block=<td.Function tf_fn=\'maximum\'>>', tdb.Mean(name='foo'): '<td.Mean \'foo\'>', tdb.OneOf(ord, (tdb.Scalar(), tdb.Scalar()), name='x'): '<td.OneOf \'x\'>', tdb.Optional(tdb.Scalar(), name='foo'): '<td.Optional \'foo\' some_case_block=<td.Scalar dtype=\'float32\'>>', tdb.Concat(1, True, 'x'): '<td.Concat \'x\' concat_dim=1 flatten=True>', tdb.Broadcast(name='x'): '<td.Broadcast \'x\'>', tdb.Zip(name='x'): '<td.Zip \'x\'>', tdb.NGrams(n=42, name='x'): '<td.NGrams \'x\' n=42>', tdb.OneHot(2, 3, name='x'): '<td.OneHot \'x\' dtype=\'float32\' start=2 stop=3>', tdb.OneHot(3): '<td.OneHot dtype=\'float32\' start=0 stop=3>', tdb.OneHotFromList(['a', 'b']): '<td.OneHotFromList>', tdb.OneHotFromList(['a', 'b'], name='foo'): '<td.OneHotFromList \'foo\'>', tdb.Nth(name='x'): '<td.Nth \'x\'>', tdb.Zeros([], 'x'): '<td.Zeros \'x\'>', tdb.Void(): '<td.Void>', tdb.Void('foo'): '<td.Void \'foo\'>', tdm.Metric('foo'): '<td.Metric \'foo\'>'} for block, expected_repr in sorted(six.iteritems(goldens), key=lambda kv: kv[1]): self.assertEqual(repr(block), expected_repr)
def test_eval_metrics_different_lengths(self): b = tdb.Record((tdb.Map(tdb.Scalar('int32') >> tdm.Metric('x')), tdb.Map(tdb.Scalar() >> tdm.Metric('y')))) desired = ([None, None], [None]), {'x': [1, 2], 'y': [3.]} self.assertBuilds(desired, b, ([1, 2], [3]))