def testConv(self): np.random.seed(7) with self.test_session() as sess: for _ in range(16): sizes = np.random.randint(3, size=1 + np.random.randint(3)) depth = np.random.randint(3) dims = np.random.randint(3, 6, size=1 + depth) seqs = jagged.pack([np.random.randn(s, dims[0]).astype(np.float32) for s in sizes]) widths = np.array([1, 3, 5, 7])[np.random.randint(4, size=depth)] filters = [np.random.randn(widths[i], dims[i], dims[i + 1]).astype(np.float32) for i in range(depth)] activations = np.array( [None, tf.nn.relu, tf.sigmoid])[np.random.randint( 3, size=depth)] out = jagged.conv1d_stack(seqs, filters, activations) self.assertEqual(type(out), jagged.Jagged) offsets, flat = sess.run([out.offsets, out.flat]) for i in range(len(sizes)): x = seqs[i][None] for filt, activation in zip(filters, activations): x = tf.nn.conv1d(x, filt, stride=1, padding='SAME') if activation is not None: x = activation(x) x = tf.squeeze(x, [0]) self.assertAllClose(flat[offsets[i]:offsets[i + 1]], x.eval())
def testBasicsAndPack(self): np.random.seed(7) with self.test_session(): for _ in range(32): sizes = np.random.randint(3, size=1 + np.random.randint(3)) seqs = [np.random.randn(s, 3) for s in sizes] jag = jagged.pack(seqs) self.assertEqual(type(jag), jagged.Jagged) self.assertAllEqual(jag.offsets.eval(), np.cumsum(np.concatenate([[0], sizes]))) self.assertAllEqual(jag.flat.eval(), np.concatenate(seqs)) self.assertEqual(jag.size.eval(), len(seqs)) for i, seq in enumerate(seqs): self.assertAllEqual(jag[i].eval(), seq)
def testMax(self): np.random.seed(7) with self.test_session(): for _ in range(16): sizes = 1 + np.random.randint(4, size=1 + np.random.randint(3)) dim = np.random.randint(3) seqs = jagged.pack([np.random.randn(s, dim) for s in sizes]) maxes = jagged.reduce_max(seqs) np_maxes = maxes.eval() self.assertEqual(np_maxes.shape, (len(sizes), dim)) for i in range(len(sizes)): self.assertAllEqual(seqs[i].eval().max(axis=0), np_maxes[i]) # Check gradient error = tf.test.compute_gradient_error(seqs.flat, (np.sum(sizes), dim), maxes, np_maxes.shape) self.assertLess(error, 1e-10)
def inference(hparams): """Make a clause search graph suitable for inference at proof time. Each described node has the correct name, for purposes of C++ lookup: conjecture, clauses: string, shape (?,), placeholders of serialized FastClause protos. conjecture_embeddings: float32, shape (dim,). logits: float32, shape (?,) output logits. initialize: Initialization op. Args: hparams: Hyperparameters. See default_hparams for details. Returns: The tf.Saver object. Raises: ValueError: If the model kind is not 'tree' or 'sequence'. """ if hparams.use_averages: raise NotImplementedError( 'Figure out how to eval with Polyak averaging') kind, model = all_models.make_model(name=hparams.model, mode='eval', hparams=hparams, vocab=FLAGS.vocab) # Input placeholders, which will hold FastClause protos. conjecture = tf.placeholder(name='conjecture', shape=(None, ), dtype=tf.string) clauses = tf.placeholder(name='clauses', shape=(None, ), dtype=tf.string) def expand(embedding): """Tile the one conjecture to match clauses.""" embeddings = tf.tile(embedding, tf.stack([tf.size(clauses), 1])) embeddings.set_shape([None, embedding.get_shape()[-1]]) return embeddings if kind == 'sequence': # Embedding weights vocab_size, _ = inputs.read_vocab(FLAGS.vocab) params = model_utils.embedding_weights(dim=hparams.embedding_size, size=vocab_size) # Embed conjecture ids = gen_clause_ops.fast_clauses_as_sequence(conjecture, conjunction=True) ids = tf.nn.embedding_lookup(params, ids) ids = ids[ None] # Singleton batch since many clauses are one ~conjecture conjecture_embedding = with_name(model.conjecture_embedding(ids), name='conjecture_embeddings') # Embed clauses ids = gen_clause_ops.fast_clauses_as_sequence(clauses) ids = tf.nn.embedding_lookup(params, ids) clause_embeddings = model.axiom_embedding(ids) # Classify logits = model.classifier(expand(conjecture_embedding), clause_embeddings) elif kind == 'tree': def weave(embed, conjecture_apply, conjecture_not, conjecture_or, conjecture_and, clause_apply, clause_not, clause_or, combine): """Weave conjecture and clauses separately, then combine.""" # Embed conjecture, naming a concatenated version for simplicity parts = clause_loom.weave_fast_clauses(clauses=conjecture, embed=embed, apply_=conjecture_apply, not_=conjecture_not, or_=conjecture_or, and_=conjecture_and, shuffle=False) concat = tf.concat(parts, 1, name='conjecture_embeddings') splits = tf.split(concat, [p.get_shape()[1].value for p in parts], axis=1) splits = [expand(s) for s in splits] # Embed clauses clause_embeddings = clause_loom.weave_fast_clauses( clauses=clauses, embed=embed, apply_=clause_apply, not_=clause_not, or_=clause_or, shuffle=False) # Combine into logits return combine.instantiate_batch(splits + list(clause_embeddings)) logits, = model(weave) elif kind == 'fast': logits = model(jagged.pack([conjecture]), clauses) else: raise ValueError('Unknown kind %r' % kind) # Fix and name logits with_name(fix_logits(kind, logits), name='logits') # Add init op for testing purposes with_name(tf.global_variables_initializer(), name='initialize') # Add saver and init ops (the latter only for test purposes) return tf.train.Saver()