import tensorflow as tf

        if self.maxnorm is not None:
            # Ensure maxnorm constraints are initially satisfied
            head_init = dense_maxnorm(head_init, self.maxnorm)
            rel_init = dense_maxnorm(rel_init, self.maxnorm)
            tail_init = dense_maxnorm(tail_init, self.maxnorm)
        self.head_embedding_vars = tf.Variable(head_init)
        self.rel_embedding_vars = tf.Variable(rel_init)
        self.tail_embedding_vars = tf.Variable(tail_init)
        # Embedding layer for each (head, rel, tail) triple being fed in as input
        head_embed = tf.nn.embedding_lookup(self.head_embedding_vars, self.head_input)
        rel_embed = tf.nn.embedding_lookup(self.rel_embedding_vars, self.rel_input)
        tail_embed = tf.nn.embedding_lookup(self.tail_embedding_vars, self.tail_input)
        # Model output
        raw_output = tf.reduce_sum(tf.mul(tf.mul(head_embed, rel_embed), tail_embed), 1)
        self.output, self.loss = self._create_output_and_loss(raw_output)
        # Optimization
        self.train_step = self.opt.minimize(self.loss)
        if self.maxnorm is not None:
            # Post-processing to limit embedding vars to L2 ball
            head_constraint = self._norm_constraint_op(self.head_embedding_vars, 
                                                       tf.unique(self.head_input)[0], 
                                                       self.maxnorm)
            rel_constraint = self._norm_constraint_op(self.rel_embedding_vars, 
                                                      tf.unique(self.rel_input)[0], 
                                                      self.maxnorm)
            tail_constraint = self._norm_constraint_op(self.tail_embedding_vars, 
