def __init__(self,
                 timed_session,
                 configs,
                 policy='random',
                 max_chats_per_config=10,
                 db='trials.pkl'):
        """A parameterized rulebased bot that can optimize its parameters.

        Args:
            timed_session (bool)
            configs (list(tuple)): each config is a tuple of numbers/strings
            policy (str): exploration strategy
            max_chats_per_config (int)
            db (str): path to dump evaluation results

        """
        super(ConfigurableRulebasedSystem, self).__init__(timed_session)
        self.configs = configs
        self.policy = policy
        self.max_chats_per_config = max_chats_per_config
        # Save evaluation results of each config
        self.db = db
        if os.path.exists(self.db):
            self.trials = read_pickle(self.db)
        else:
            self.trials = defaultdict(dict)
        # The web server can update trials with multiple threads
        self.lock = Lock()
Beispiel #2
0
    def __init__(self,
                 schema,
                 learned_lex,
                 stop_words=None,
                 lexicon_path=None):
        self.schema = schema
        # if True, lexicon uses learned system
        self.learned_lex = learned_lex
        self.entities = set()
        self.word_counts = defaultdict(
            int)  # Counts of words that show up in entities
        self.lexicon = defaultdict(
            list)  # Mapping from string -> list of (entity, type)
        with open(stop_words, 'r') as fin:
            self.stop_words = set([x.strip()
                                   for x in fin.read().split()][:1000])
            self.stop_words.update([
                'one', '1', 'two', '2', 'three', '3', 'four', '4', 'five', '5',
                'six', '6', 'seven', '7', 'eight', '8', 'nine', '9', 'ten',
                '10'
            ])
        self.load_entities()

        if not lexicon_path or not os.path.exists(lexicon_path):
            self.compute_synonyms()
            print 'Created lexicon: %d phrases mapping to %d entities, %f entities per phrase' % (
                len(self.lexicon), len(self.entities),
                sum([len(x) for x in self.lexicon.values()]) /
                float(len(self.lexicon)))
            if lexicon_path is not None:
                print 'Dump lexicon to {}'.format(lexicon_path)
                write_pickle(self.lexicon, lexicon_path)
        else:
            print 'Load lexicon from {}'.format(lexicon_path)
            self.lexicon = read_pickle(lexicon_path)
Beispiel #3
0
    def __init__(self, schema, lexicon, model_path, fact_check, decoding, timed_session=False, consecutive_entity=True, realizer=None):
        super(NeuralSystem, self).__init__()
        self.schema = schema
        self.lexicon = lexicon
        self.timed_session = timed_session
        self.consecutive_entity = consecutive_entity

        # Load arguments
        args_path = os.path.join(model_path, 'config.json')
        config = read_json(args_path)
        config['batch_size'] = 1
        config['gpu'] = 0  # Don't need GPU for batch_size=1
        config['decoding'] = decoding
        args = argparse.Namespace(**config)

        mappings_path = os.path.join(model_path, 'vocab.pkl')
        mappings = read_pickle(mappings_path)
        vocab = mappings['vocab']

        # TODO: different models have the same key now
        args.dropout = 0
        logstats.add_args('model_args', args)
        model = build_model(schema, mappings, args)

        # Tensorflow config
        if args.gpu == 0:
            print 'GPU is disabled'
            config = tf.ConfigProto(device_count = {'GPU': 0})
        else:
            gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.5, allow_growth=True)
            config = tf.ConfigProto(device_count = {'GPU': 1}, gpu_options=gpu_options)

        # NOTE: need to close the session when done
        tf_session = tf.Session(config=config)
        tf.initialize_all_variables().run(session=tf_session)

        # Load TF model parameters
        ckpt = tf.train.get_checkpoint_state(model_path+'-best')
        assert ckpt, 'No checkpoint found'
        assert ckpt.model_checkpoint_path, 'No model path found in checkpoint'
        saver = tf.train.Saver()
        saver.restore(tf_session, ckpt.model_checkpoint_path)

        self.model_name = args.model
        if self.model_name == 'attn-copy-encdec':
            args.entity_target_form = 'graph'
            copy = True
        else:
            copy = False
        preprocessor = Preprocessor(schema, lexicon, args.entity_encoding_form, args.entity_decoding_form, args.entity_target_form, args.prepend)
        textint_map = TextIntMap(vocab, mappings['entity'], preprocessor)

        Env = namedtuple('Env', ['model', 'tf_session', 'preprocessor', 'vocab', 'copy', 'textint_map', 'stop_symbol', 'remove_symbols', 'max_len', 'evaluator', 'prepend', 'consecutive_entity', 'realizer'])
        self.env = Env(model, tf_session, preprocessor, mappings['vocab'], copy, textint_map, stop_symbol=vocab.to_ind(markers.EOS), remove_symbols=map(vocab.to_ind, (markers.EOS, markers.PAD)), max_len=20, evaluator=FactEvaluator() if fact_check else None, prepend=args.prepend, consecutive_entity=self.consecutive_entity, realizer=realizer)
Beispiel #4
0
    def __init__(self, schema, price_tracker, retriever, model_path, mappings, timed_session=False):
        super(NeuralRankerSystem, self).__init__()
        self.schema = schema
        self.price_tracker = price_tracker
        self.timed_session = timed_session

        # Load arguments
        args_path = os.path.join(model_path, 'config.json')
        config = read_json(args_path)
        # TODO: handle this properly
        config['batch_size'] = 1
        config['pretrained_wordvec'] = None
        args = argparse.Namespace(**config)

        mappings_path = os.path.join(mappings, 'vocab.pkl')
        mappings = read_pickle(mappings_path)
        vocab = mappings['vocab']

        logstats.add_args('model_args', args)
        model = build_model(schema, mappings, None, args)

        # Tensorflow config
        if args.gpu == 0:
            print 'GPU is disabled'
            config = tf.ConfigProto(device_count = {'GPU': 0})
        else:
            gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.5, allow_growth=True)
            config = tf.ConfigProto(device_count = {'GPU': 1}, gpu_options=gpu_options)
        os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

        # NOTE: need to close the session when done
        tf_session = tf.Session(config=config)
        tf_session.run(tf.global_variables_initializer())

        # Load TF model parameters
        ckpt = tf.train.get_checkpoint_state(model_path+'-best')
        assert ckpt, 'No checkpoint found'
        assert ckpt.model_checkpoint_path, 'No model path found in checkpoint'
        saver = tf.train.Saver()
        saver.restore(tf_session, ckpt.model_checkpoint_path)

        preprocessor = Preprocessor(schema, price_tracker, 'canonical', 'canonical', 'canonical')
        textint_map = TextIntMap(vocab, preprocessor)

        int_markers = SpecialSymbols(*[mappings['vocab'].to_ind(m) for m in markers])
        model_config = {'retrieve': True}
        batcher = DialogueBatcherFactory.get_dialogue_batcher(model_config, int_markers=int_markers, slot_filling=False, kb_pad=mappings['kb_vocab'].to_ind(markers.PAD))

        StreamingDialogue.textint_map = textint_map
        StreamingDialogue.num_context = args.num_context
        StreamingDialogue.mappings = mappings

        Env = namedtuple('Env', ['ranker', 'retriever', 'tf_session', 'preprocessor', 'mappings', 'textint_map', 'batcher'])
        self.env = Env(model, retriever, tf_session, preprocessor, mappings, textint_map, batcher)
Beispiel #5
0
    def create_batches(self, split_type):
        raw_data = read_pickle("data/{}_batches.pkl".format(split_type))
        data = []
        for example in raw_data:
            source_tokens = example[0]
            source_indexes = [self.vocab.word_to_ind[st] for st in source_tokens]
            source = basic_variable(source_indexes)

            target_tokens = example[1]
            target_indexes = [self.vocab.word_to_ind[tt] for tt in target_tokens]
            target = basic_variable(target_indexes)

            data.append((source, target))
        return data
Beispiel #6
0
    def create_batches(self,
                       name,
                       dialogues,
                       batch_size,
                       add_ground_truth=True):
        if not os.path.isdir(self.cache):
            os.makedirs(self.cache)
        cache_file = os.path.join(self.cache, '%s_batches.pkl' % name)
        if (not os.path.exists(cache_file)) or self.ignore_cache:
            if self.retriever is not None:
                for dialogue in dialogues:
                    k = (dialogue.uuid, dialogue.role)
                    # candidates: list of list containing num_candidates responses for each turn of the dialogue
                    # None candidates means that it is not the agent's speaking turn
                    if k in self.cached_candidates:
                        candidates = self.cached_candidates[k]
                    else:
                        candidates = self.retriever.retrieve_candidates(
                            dialogue, json_dict=False)

                    #if self.slot_filling:
                    #    for turn_candidates in candidates:
                    #        if turn_candidates:
                    #            for c in turn_candidates:
                    #                if 'response' in c:
                    #                    c['response'] = Preprocessor._mark_slots(c['response'])
                    #                    #print c['response']
                    #candidates = [c if c else self.retriever.empty_candidates for c in candidates]

                    dialogue.add_candidates(candidates,
                                            add_ground_truth=add_ground_truth)
                self.retriever.report_search_time()

            for dialogue in dialogues:
                dialogue.convert_to_int()

            dialogue_batches = self.create_dialogue_batches(
                dialogues, batch_size)
            print 'Write %d batches to cache %s' % (len(dialogue_batches),
                                                    cache_file)
            start_time = time.time()
            write_pickle(dialogue_batches, cache_file)
            print '[%d s]' % (time.time() - start_time)
        else:
            start_time = time.time()
            dialogue_batches = read_pickle(cache_file)
            print 'Read %d batches from cache %s' % (len(dialogue_batches),
                                                     cache_file)
            print '[%d s]' % (time.time() - start_time)
        return dialogue_batches
Beispiel #7
0
 def load_mappings(self, model_type, mappings_path, schema, preprocessor):
     vocab_path = os.path.join(mappings_path, 'vocab.pkl')
     if not os.path.exists(vocab_path):
         print 'Vocab not found at', vocab_path
         mappings = create_mappings(self.dialogues['train'], schema,
             preprocessor.entity_forms.values())
         write_pickle(mappings, vocab_path)
         print('Wrote mappings to {}.'.format(vocab_path))
     else:
         print 'Loading vocab from', vocab_path
         mappings = read_pickle(vocab_path)
         for k, v in mappings.iteritems():
             print k, v.size
         mappings = make_model_mappings(model_type, mappings)
         return mappings
Beispiel #8
0
    def create_batches(self, name, dialogues, batch_size):
        if not os.path.isdir(self.cache):
            os.makedirs(self.cache)
        cache_file = os.path.join(self.cache, '%s_batches.pkl' % name)
        if (not os.path.exists(cache_file)) or self.ignore_cache:
            for dialogue in dialogues:
                dialogue.convert_to_int()

            dialogue_batches = self.create_dialogue_batches(dialogues, batch_size)
            print 'Write %d batches to cache %s' % (len(dialogue_batches), cache_file)
            start_time = time.time()
            write_pickle(dialogue_batches, cache_file)
            print '[%d s]' % (time.time() - start_time)
        else:
            start_time = time.time()
            dialogue_batches = read_pickle(cache_file)
            print 'Read %d batches from cache %s' % (len(dialogue_batches), cache_file)
            print '[%d s]' % (time.time() - start_time)
        return dialogue_batches
Beispiel #9
0
    def create_trie(self, batches, path):
        if path is None:
            return None

        def seq_iter(batches):
            for batch in batches:
                for b in batch['batch_seq']:
                    targets = b['targets']
                    for target in targets:
                        yield target

        if not os.path.exists(path):
            trie = Trie()
            print 'Build prefix trie of length', trie.max_prefix_len
            start_time = time.time()
            trie.build_trie(seq_iter(batches))
            print '[%d s]' % (time.time() - start_time)
            print 'Write trie to', path
            write_pickle(trie, path)
        else:
            print 'Read trie from', path
            trie = read_pickle(path)
        return trie
Beispiel #10
0
 def from_pickle(cls, path):
     templates = read_pickle(path)
     return cls(templates)
Beispiel #11
0
    def __init__(self,
                 schema,
                 price_tracker,
                 model_path,
                 mappings_path,
                 decoding,
                 index=None,
                 num_candidates=20,
                 retriever_context_len=2,
                 timed_session=False):
        super(NeuralSystem, self).__init__()
        self.schema = schema
        self.price_tracker = price_tracker
        self.timed_session = timed_session

        # Load arguments
        args_path = os.path.join(model_path, 'config.json')
        config = read_json(args_path)
        config['batch_size'] = 1
        config['gpu'] = 0  # Don't need GPU for batch_size=1
        config['decoding'] = decoding
        config['pretrained_wordvec'] = None
        args = argparse.Namespace(**config)

        vocab_path = os.path.join(mappings_path, 'vocab.pkl')
        mappings = read_pickle(vocab_path)
        vocab = mappings['vocab']

        # TODO: different models have the same key now
        args.dropout = 0
        logstats.add_args('model_args', args)
        model = build_model(schema, mappings, None, args)

        # Tensorflow config
        if args.gpu == 0:
            print 'GPU is disabled'
            config = tf.ConfigProto(device_count={'GPU': 0})
        else:
            gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.5,
                                        allow_growth=True)
            config = tf.ConfigProto(device_count={'GPU': 1},
                                    gpu_options=gpu_options)

        # NOTE: need to close the session when done
        tf_session = tf.Session(config=config)
        tf.initialize_all_variables().run(session=tf_session)

        # Load TF model parameters
        ckpt = tf.train.get_checkpoint_state(model_path + '-best')
        assert ckpt, 'No checkpoint found'
        assert ckpt.model_checkpoint_path, 'No model path found in checkpoint'
        saver = tf.train.Saver()
        saver.restore(tf_session, ckpt.model_checkpoint_path)

        # Model config tells data generator which batcher to use
        model_config = {}
        if args.retrieve or args.model in ('ir', 'selector'):
            model_config['retrieve'] = True
        if args.predict_price:
            model_config['price'] = True

        self.model_name = args.model
        preprocessor = Preprocessor(schema, price_tracker,
                                    args.entity_encoding_form,
                                    args.entity_decoding_form,
                                    args.entity_target_form)
        textint_map = TextIntMap(vocab, preprocessor)
        int_markers = SpecialSymbols(
            *[mappings['vocab'].to_ind(m) for m in markers])
        dialogue_batcher = DialogueBatcherFactory.get_dialogue_batcher(
            model_config,
            int_markers=int_markers,
            slot_filling=False,
            kb_pad=mappings['kb_vocab'].to_ind(markers.PAD))

        # Retriever
        if args.model == 'selector':
            retriever = Retriever(index,
                                  context_size=retriever_context_len,
                                  num_candidates=num_candidates)
        else:
            retriever = None

        #TODO: class variable is not a good way to do this
        Dialogue.mappings = mappings
        Dialogue.textint_map = textint_map
        Dialogue.preprocessor = preprocessor
        Dialogue.num_context = args.num_context

        Env = namedtuple('Env', [
            'model', 'tf_session', 'preprocessor', 'vocab', 'textint_map',
            'stop_symbol', 'remove_symbols', 'max_len', 'dialogue_batcher',
            'retriever'
        ])
        self.env = Env(model,
                       tf_session,
                       preprocessor,
                       mappings['vocab'],
                       textint_map,
                       stop_symbol=vocab.to_ind(markers.EOS),
                       remove_symbols=map(vocab.to_ind,
                                          (markers.EOS, markers.PAD)),
                       max_len=20,
                       dialogue_batcher=dialogue_batcher,
                       retriever=retriever)
Beispiel #12
0
        if not os.path.isdir(args.checkpoint):
            os.makedirs(args.checkpoint)
        config_path = os.path.join(args.checkpoint, 'config.json')
        write_json(vars(args), config_path)
        model_args = args
        ckpt = None

    # Load vocab
    vocab_path = 'data/persona_vocab.pkl'
    if not os.path.exists(vocab_path):
        print 'Vocab not found at', vocab_path
        vocab = None
        args.ignore_cache = True
    else:
        print 'Loading vocab from', vocab_path
        vocab = read_pickle(vocab_path)

    # schema = Schema(model_args.schema_path, None)
    # train_batches = DialogueBatcher(vocab, "train")
    # val_batches = DialogueBatcher(vocab, "valid")

    if cuda.is_available():
        print 'Using GPU'
        encoder = encoder.cuda()
        decoder = decoder.cuda()
    else:
        print 'GPU is disabled'

    # for d, n in data_generator.num_examples.iteritems():
    #     logstats.add('data', d, 'num_dialogues', n)
Beispiel #13
0
 def from_pickle(cls, path):
     data = read_pickle(path)
     return cls(**data)
Beispiel #14
0
 def from_pickle(cls, path):
     data = read_pickle(path)
     return cls(data['model'], data['actions'])
Beispiel #15
0
 def from_pickle(cls, path):
     templates = read_pickle(path)
     return cls(templates=templates, finalized=True)
Beispiel #16
0
 def __init__(self, model_path):
     self.model = read_pickle(model_path)
Beispiel #17
0
            os.makedirs(args.checkpoint)
        config_path = os.path.join(args.checkpoint, 'config.json')
        write_json(vars(args), config_path)
        model_args = args
        ckpt = None

    # Load vocab
    # TODO: put this in DataGenerator
    vocab_path = os.path.join(model_args.mappings, 'vocab.pkl')
    if not os.path.exists(vocab_path):
        print 'Vocab not found at', vocab_path
        mappings = None
        args.ignore_cache = True
    else:
        print 'Load vocab from', vocab_path
        mappings = read_pickle(vocab_path)
        for k, v in mappings.iteritems():
            print k, v.size

    schema = Schema(model_args.schema_path, None)

    data_generator = get_data_generator(args, model_args, mappings, schema)

    for d, n in data_generator.num_examples.iteritems():
        logstats.add('data', d, 'num_dialogues', n)

    # Save mappings
    if not mappings:
        mappings = data_generator.mappings
        vocab_path = os.path.join(args.mappings, 'vocab.pkl')
        write_pickle(mappings, vocab_path)