import tensorflow as tf

        self.batch_pos_cnt = batch_pos_cnt
        self.max_iter = max_iter
        self.model_type = model_type
        self.add_bias = add_bias
        if opt is None:
            opt = tf.train.AdagradOptimizer(1.0)
        self.opt = opt
        self.sess = None
        self.train_step = None
        self.post_step = None
        self.graph = tf.Graph()
        with self.graph.as_default():
            self.head_input = tf.placeholder(tf.int32, shape=[None])
            self.rel_input = tf.placeholder(tf.int32, shape=[None])
            self.tail_input = tf.placeholder(tf.int32, shape=[None])
            self.target = tf.placeholder(tf.float32, shape=[None])

    def _create_model(self, train_triples):
        ''' Subclasses must build Graph and set self.train_step '''
        raise Exception('subclass must implement')
    
    def _create_batch_provider(self, train_triples):
        ''' Default implementation '''
        return ContrastiveTrainingProvider(train_triples, self.batch_pos_cnt)
    
    def _create_output_and_loss(self, raw_output):
