Ejemplo n.º 1
0
    def _convert_batch(self, py_batch):
        degree_input_np = np.array(py_batch['degree'])
        u_input_np = pad_sequences(py_batch['user'],
                                   cfg.u_max_ts,
                                   padding='post',
                                   truncating='pre').transpose((1, 0))
        z_input_np = pad_sequences(py_batch['latent'],
                                   padding='post').transpose((1, 0))
        m_input_np = pad_sequences(py_batch['response'],
                                   cfg.max_ts,
                                   padding='post',
                                   truncating='post').transpose((1, 0))
        # fix p input
        p_input_np = pad_sequences(py_batch['post'],
                                   cfg.u_max_ts,
                                   padding='post',
                                   truncating='post').transpose((1, 0))
        u_len = np.array(py_batch['u_len'])
        m_len = np.array(py_batch['m_len'])
        p_len = np.array(py_batch['p_len'])

        degree_input = Variable(torch.from_numpy(degree_input_np).float())
        u_input = Variable(torch.from_numpy(u_input_np).long())
        z_input = Variable(torch.from_numpy(z_input_np).long())
        m_input = Variable(torch.from_numpy(m_input_np).long())
        p_input = Variable(torch.from_numpy(p_input_np).long())
        if cfg.cuda:
            u_input, z_input, m_input, p_input, degree_input = u_input.cuda(), z_input.cuda(), m_input.cuda(),\
                                                               p_input.cuda(), degree_input.cuda()
        supervised = py_batch['supervised'][0]
        return u_input, u_input_np, z_input, m_input, m_input_np, p_input, p_input_np, u_len, m_len, p_len,\
               degree_input, supervised
Ejemplo n.º 2
0
    def _convert_batch_para(self, py_batch, mode, prev_a_py=None):
        u_input_np = pad_sequences(py_batch['delex_user'], cfg.max_para_len, padding='post',
                                   truncating='pre').transpose((1, 0))
        delex_para_input_np = pad_sequences(py_batch['delex_para'], cfg.max_para_len, padding='post',
                                            truncating='pre').transpose((1, 0))
        u_len = np.array(py_batch['delex_u_len'])
        u_input = cuda_(Variable(torch.from_numpy(u_input_np).long()))
        delex_para_input = cuda_(Variable(torch.from_numpy(delex_para_input_np).long()))
        if mode == 'test':
            if prev_a_py:
                for i in range(len(prev_a_py)):
                    eob = self.reader.vocab.encode('EOS_A')
                    if eob in prev_a_py[i] and prev_a_py[i].index(eob) != len(prev_a_py[i]) - 1:
                        idx = prev_a_py[i].index(eob)
                        prev_a_py[i] = prev_a_py[i][:idx + 1]
                    else:
                        prev_a_py[i] = [eob]
                    for j, word in enumerate(prev_a_py[i]):
                        if word >= cfg.vocab_size or word < 0:
                            prev_a_py[i][j] = 2 #unk
            else:
                prev_a_py = py_batch['pre_dial_act']
            prev_dial_act_input_np = pad_sequences(prev_a_py, cfg.a_length, padding='post', truncating='pre').transpose((1, 0))
            prev_dial_act_input = cuda_(Variable(torch.from_numpy(prev_dial_act_input_np).long()))
        else:
            prev_dial_act_input_np = pad_sequences(py_batch['pre_dial_act'], cfg.a_length, padding='post',
                                                   truncating='pre').transpose((1, 0))
            prev_dial_act_input = cuda_(Variable(torch.from_numpy(prev_dial_act_input_np).long()))

        return u_input, u_input_np, delex_para_input, delex_para_input_np, u_len, prev_dial_act_input
Ejemplo n.º 3
0
    def _convert_batch(self, py_batch, prev_z_py=None, mode="train"):
        domain = py_batch['domain']
        if mode == "train":
            u_input_py = py_batch['final_user']
            u_len_py = py_batch['final_u_len']
        else:
            u_input_py = py_batch['user']
            u_len_py = py_batch['u_len']
        kw_ret = {}
        if cfg.prev_z_method == 'concat' and prev_z_py is not None:
            for i in range(len(u_input_py)):
                eob = self.reader.vocab.encode('EOS_Z2')
                if eob in prev_z_py[i] and prev_z_py[i].index(eob) != len(prev_z_py[i]) - 1:
                    idx = prev_z_py[i].index(eob)
                    u_input_py[i] = prev_z_py[i][:idx + 1] + u_input_py[i]
                else:
                    u_input_py[i] = prev_z_py[i] + u_input_py[i]
                u_len_py[i] = len(u_input_py[i])
                for j, word in enumerate(prev_z_py[i]):
                    if word >= cfg.vocab_size or word < 0:
                        prev_z_py[i][j] = 2 #unk
        elif cfg.prev_z_method == 'separate' and prev_z_py is not None:
            for i in range(len(prev_z_py)):
                eob = self.reader.vocab.encode('EOS_Z2')
                if eob in prev_z_py[i] and prev_z_py[i].index(eob) != len(prev_z_py[i]) - 1:
                    idx = prev_z_py[i].index(eob)
                    prev_z_py[i] = prev_z_py[i][:idx + 1]
                for j, word in enumerate(prev_z_py[i]):
                    if word >= cfg.vocab_size:
                        prev_z_py[i][j] = 2 #unk
            prev_z_input_np = pad_sequences(prev_z_py, cfg.max_ts, padding='post', truncating='pre').transpose((1, 0))
            prev_z_len = np.array([len(_) for _ in prev_z_py])
            prev_z_input = cuda_(Variable(torch.from_numpy(prev_z_input_np).long()))
            kw_ret['prev_z_len'] = prev_z_len
            kw_ret['prev_z_input'] = prev_z_input
            kw_ret['prev_z_input_np'] = prev_z_input_np

        degree_input_np = np.array(py_batch['degree'])
        u_input_np = pad_sequences(u_input_py, cfg.max_ts, padding='post', truncating='pre').transpose((1, 0))
        z_input_np = pad_sequences(py_batch['bspan'], padding='post').transpose((1, 0))
        m_input_np = pad_sequences(py_batch['response'], cfg.max_ts, padding='post', truncating='post').transpose(
            (1, 0))

        u_len = np.array(u_len_py)
        m_len = np.array(py_batch['m_len'])

        degree_input = cuda_(Variable(torch.from_numpy(degree_input_np).float()))
        u_input = cuda_(Variable(torch.from_numpy(u_input_np).long()))
        z_input = cuda_(Variable(torch.from_numpy(z_input_np).long()))
        m_input = cuda_(Variable(torch.from_numpy(m_input_np).long()))

        kw_ret['z_input_np'] = z_input_np

        return u_input, u_input_np, z_input, m_input, m_input_np, u_len, m_len, degree_input, kw_ret, domain
Ejemplo n.º 4
0
    def _convert_batch_para(self, py_batch, mode, prev_a_py=None):
        combined_input = []
        combined_length = []
        for prev_response, delex_user in zip(py_batch['pv_resp'],
                                             py_batch['usdx']):
            combined_input.append(prev_response + delex_user)
            combined_length.append(len(prev_response + delex_user))
        u_input_np = pad_sequences(combined_input,
                                   cfg.max_nl_length,
                                   padding='post',
                                   truncating='pre').transpose((1, 0))
        u_len = np.array(combined_length)
        delex_para_input_np = pad_sequences(py_batch['padx'],
                                            cfg.max_nl_length,
                                            padding='post',
                                            truncating='pre').transpose((1, 0))
        u_input = cuda_(torch.from_numpy(u_input_np).long())
        delex_para_input = cuda_(torch.from_numpy(delex_para_input_np).long())
        if mode == 'test':
            if prev_a_py:
                for i in range(len(prev_a_py)):
                    eob = self.reader.vocab.encode('<eos_a>')
                    if eob in prev_a_py[i] and prev_a_py[i].index(eob) != len(
                            prev_a_py[i]) - 1:
                        idx = prev_a_py[i].index(eob)
                        prev_a_py[i] = prev_a_py[i][:idx + 1]
                    else:
                        prev_a_py[i] = [eob]
                    '''
                    for j, word in enumerate(prev_a_py[i]):
                        if word >= cfg.vocab_size:
                            prev_a_py[i][j] = 2 #unk
                    '''
            else:
                prev_a_py = py_batch['pv_aspn']
            prev_dial_act_input_np = pad_sequences(prev_a_py,
                                                   cfg.max_nl_length,
                                                   padding='post',
                                                   truncating='pre').transpose(
                                                       (1, 0))
            prev_dial_act_input = cuda_(
                torch.from_numpy(prev_dial_act_input_np).long())
        else:
            prev_dial_act_input_np = pad_sequences(py_batch['pv_aspn'],
                                                   cfg.max_nl_length,
                                                   padding='post',
                                                   truncating='pre').transpose(
                                                       (1, 0))
            prev_dial_act_input = cuda_(
                torch.from_numpy(prev_dial_act_input_np).long())

        return u_input, u_input_np, delex_para_input, delex_para_input_np, u_len, prev_dial_act_input
Ejemplo n.º 5
0
    def _convert_input(self, encoded_input):
        u_input_np = pad_sequences([encoded_input],
                                   cfg.max_ts,
                                   padding='post',
                                   truncating='pre').transpose((1, 0))
        u_input = cuda_(Variable(torch.from_numpy(u_input_np).long()))

        u_len = np.array([len(encoded_input)])

        db_found = self.reader._degree_vec_mapping(1)
        degree_input_np = np.array([db_found])
        degree_input = cuda_(
            Variable(torch.from_numpy(degree_input_np).float()))

        return u_input, u_input_np, u_len, degree_input
Ejemplo n.º 6
0
 def greedy_decode(self, pz_dec_outs, u_enc_out, m_tm1, u_input_np, last_hidden, degree_input, bspan_index):
     decoded = []
     bspan_index_np = pad_sequences(bspan_index).transpose((1, 0))
     for t in range(self.max_ts):
         proba, last_hidden, _ = self.m_decoder(pz_dec_outs, u_enc_out, u_input_np, m_tm1,
                                                degree_input, last_hidden, bspan_index_np)
         mt_proba, mt_index = torch.topk(proba, 1)  # [B,1]
         mt_index = mt_index.data.view(-1)
         decoded.append(mt_index.clone())
         for i in range(mt_index.size(0)):
             if mt_index[i] >= cfg.vocab_size:
                 mt_index[i] = 2  # unk
         m_tm1 = cuda_(Variable(mt_index).view(1, -1))
     decoded = torch.stack(decoded, dim=0).transpose(0, 1)
     decoded = list(decoded)
     return [list(_) for _ in decoded]
Ejemplo n.º 7
0
def train():
    def prepare_input(batch):
        src_ids, label = batch
        res = {}

        res['src'] = src_ids
        res['label'] = label

        return res

    # Set parameters:
    # ngram_range = 2 will add bi-grams features
    ngram_range = 2
    max_features = 20000
    maxlen = 400
    batch_size = 32
    embedding_dims = 50
    epochs = 5

    print('Loading data...')
    all_data = reader.raw_data(num_words=max_features)
    x_train, y_train, x_test, y_test = all_data

    print(len(x_train), 'train sequences')
    print(len(x_test), 'test sequences')
    print('Average train sequence length: {}'.format(
        np.mean(list(map(len, x_train)), dtype=int)))
    print('Average test sequence length: {}'.format(
        np.mean(list(map(len, x_test)), dtype=int)))

    if ngram_range > 1:
        print('Adding {}-gram features'.format(ngram_range))
        # Create set of unique n-gram from the training set.
        ngram_set = set()
        for input_list in x_train:
            for i in range(2, ngram_range + 1):
                set_of_ngram = create_ngram_set(input_list, ngram_value=i)
                ngram_set.update(set_of_ngram)

        # Dictionary mapping n-gram token to a unique integer.
        # Integer values are greater than max_features in order
        # to avoid collision with existing features.
        start_index = max_features + 1
        token_indice = {v: k + start_index for k, v in enumerate(ngram_set)}
        indice_token = {token_indice[k]: k for k in token_indice}

        # max_features is the highest integer that could be found in the dataset.
        max_features = np.max(list(indice_token.keys())) + 1

        # Augmenting x_train and x_test with n-grams features
        x_train = add_ngram(x_train, token_indice, ngram_range)
        x_test = add_ngram(x_test, token_indice, ngram_range)
        print('Average train sequence length: {}'.format(
            np.mean(list(map(len, x_train)), dtype=int)))
        print('Average test sequence length: {}'.format(
            np.mean(list(map(len, x_test)), dtype=int)))

    print('Pad sequences (samples x time)')
    x_train = reader.pad_sequences(x_train, maxlen=maxlen)
    x_test = reader.pad_sequences(x_test, maxlen=maxlen)
    print('x_train shape:', x_train.shape)
    print('x_test shape:', x_test.shape)

    all_data = x_train, y_train, x_test, y_test

    print('Build model...')
    model = BaseModel(max_features=max_features)
    loss, acc = model.build_graph()

    main_program = fluid.default_main_program()
    inference_program = fluid.default_main_program().clone(for_test=True)

    optimizer = fluid.optimizer.Adam(0.01)
    optimizer.minimize(loss)

    place = fluid.CPUPlace()
    exe = Executor(place)
    exe.run(framework.default_startup_program())

    for epoch_id in range(epochs):
        start_time = time.time()
        print("epoch id", epoch_id)

        train_data_iter = reader.get_data_iter(all_data, batch_size)

        total_loss = 0
        total_acc = 0
        batch_id = 0
        for batch in train_data_iter:

            input_data_feed = prepare_input(batch)
            fetch_outs = exe.run(feed=input_data_feed,
                                 fetch_list=[loss.name, acc.name],
                                 use_program_cache=False)

            cost_train = np.array(fetch_outs[0])
            acc_train = np.array(fetch_outs[1])
            total_loss += cost_train
            total_acc += acc_train

            if batch_id > 0 and batch_id % 10 == 0:
                print("current loss: %.3f, current acc: %.3f for step %d" %
                      (total_loss, total_acc * 0.1, batch_id))
                total_loss = 0.0
                total_acc = 0.0

            batch_id += 1

    test_data_iter = reader.get_data_iter(all_data, batch_size, mode='test')

    all_acc = []

    for batch in test_data_iter:
        input_data_feed = prepare_input(batch)
        fetch_outs = exe.run(program=inference_program,
                             feed=input_data_feed,
                             fetch_list=[loss.name, acc.name],
                             use_program_cache=False)

        all_acc.append(fetch_outs[1])

    all_acc = np.array(all_acc).astype("float32")

    print("test acc: %.3f" % all_acc.mean())
Ejemplo n.º 8
0
    def _convert_batch(self, py_batch):
        kw_ret = {}
        x = None
        gt_y = None
        if self.cfg.network == 'classification':
            state_vector = py_batch[
                'state_vector']  #list of array (batch_size, 1, vector_size)
            batch_size = len(state_vector)
            np_x = np.stack(state_vector,
                            axis=0)  #(batch_size, 1, vector_size)
            np_x = np.squeeze(np_x, axis=1)  #(batch_size, vector_size)
            np_gt_y = np.zeros((batch_size, self.cfg.output_size),
                               dtype=float)  #(batch_size, output_size)
            for batch_id, idx_list in enumerate(py_batch['act_slot_idx_list']):
                for idx in idx_list:
                    np_gt_y[batch_id, idx] = 1.
            x = cuda_(Variable(torch.from_numpy(np_x).float()), self.cfg)
            gt_y = cuda_(Variable(torch.from_numpy(np_gt_y).float()), self.cfg)
        elif 'seq2seq' in self.cfg.network:
            user_np = pad_sequences(py_batch['user_act_seq'],
                                    self.cfg.user_max_ts,
                                    padding='post',
                                    truncating='post').transpose((1, 0))
            last_agent_np = pad_sequences(py_batch['last_agent_act_seq'],
                                          self.cfg.agent_max_ts,
                                          padding='post',
                                          truncating='post').transpose((1, 0))
            current_slot_np = pad_sequences(py_batch['current_slot_seq'],
                                            self.cfg.current_slot_max_ts,
                                            padding='post',
                                            truncating='post').transpose(
                                                (1, 0))  # (seqlen, batchsize)
            agent_np = pad_sequences(py_batch['agent_act_seq'],
                                     self.cfg.agent_max_ts,
                                     padding='post',
                                     truncating='post').transpose((1, 0))
            user_len = np.array(py_batch['user_len'])
            last_agent_len = np.array(py_batch['last_agent_len'])
            current_slot_len = np.array(py_batch['current_slot_len'])
            agent_len = np.array(py_batch['agent_len'])
            kb_turn_np = np.array(py_batch['kb_turn_vector']).transpose(
                1, 0, 2)

            kw_ret['user_np'] = user_np  #seqlen, batchsize
            kw_ret['last_agent_np'] = last_agent_np  #seqlen, batchsize
            kw_ret['current_slot_np'] = current_slot_np  #seqlen, batchsize
            kw_ret['agent_np'] = agent_np  #seqlen, batchsize
            kw_ret['user_len'] = user_len  #batchsize
            kw_ret['last_agent_len'] = last_agent_len  #batchsize
            kw_ret['current_slot_len'] = current_slot_len  #batchsize
            kw_ret['agent_len'] = agent_len  #batchsize
            kw_ret['kb_turn'] = cuda_(
                Variable(torch.from_numpy(kb_turn_np).float()),
                self.cfg)  #1, batch_size, kb_turn_size
            kw_ret['last_agent'] = cuda_(
                Variable(torch.from_numpy(last_agent_np).long()),
                self.cfg)  #seqlen, batchsize
            kw_ret['current_slot'] = cuda_(
                Variable(torch.from_numpy(current_slot_np).long()),
                self.cfg)  #seqlen, batchsize
            x = cuda_(Variable(torch.from_numpy(user_np).long()),
                      self.cfg)  #seqlen, batchsize
            gt_y = cuda_(Variable(torch.from_numpy(agent_np).long()),
                         self.cfg)  #seqlen, batchsize

        elif 'cas' in self.cfg.network:
            user_np = pad_sequences(py_batch['user_act_seq'],
                                    self.cfg.user_max_ts,
                                    padding='post',
                                    truncating='post').transpose((1, 0))
            last_agent_np = pad_sequences(py_batch['last_agent_act_seq'],
                                          self.cfg.agent_max_ts,
                                          padding='post',
                                          truncating='post').transpose((1, 0))
            current_slot_np = pad_sequences(py_batch['current_slot_seq'],
                                            self.cfg.current_slot_max_ts,
                                            padding='post',
                                            truncating='post').transpose(
                                                (1, 0))  # (seqlen, batchsize)
            current_user_request_np = pad_sequences(
                py_batch['current_user_request_seq'],
                self.cfg.current_singleslot_max_ts,
                padding='post',
                truncating='post').transpose((1, 0))  # (seqlen, batchsize)
            current_user_inform_np = pad_sequences(
                py_batch['current_user_inform_seq'],
                self.cfg.current_singleslot_max_ts,
                padding='post',
                truncating='post').transpose((1, 0))  # (seqlen, batchsize)
            current_agent_request_np = pad_sequences(
                py_batch['current_agent_request_seq'],
                self.cfg.current_singleslot_max_ts,
                padding='post',
                truncating='post').transpose((1, 0))  # (seqlen, batchsize)
            current_agent_propose_np = pad_sequences(
                py_batch['current_agent_propose_seq'],
                self.cfg.current_singleslot_max_ts,
                padding='post',
                truncating='post').transpose((1, 0))  # (seqlen, batchsize)
            user_len = np.array(py_batch['user_len'])
            last_agent_len = np.array(py_batch['last_agent_len'])
            current_slot_len = np.array(py_batch['current_slot_len'])
            current_user_request_len = np.array(
                py_batch['current_user_request_len'])
            current_user_inform_len = np.array(
                py_batch['current_user_inform_len'])
            current_agent_request_len = np.array(
                py_batch['current_agent_request_len'])
            current_agent_propose_len = np.array(
                py_batch['current_agent_propose_len'])
            kb_turn_np = np.array(py_batch['kb_turn_vector']).transpose(
                1, 0, 2)
            cas_continue_np = np.concatenate(
                py_batch['cas_continue'],
                axis=1)  #seqlen, batchsize, continuesize
            cas_act_np = np.concatenate(py_batch['cas_act'],
                                        axis=1)  #seqlen, batchsize, actsize
            cas_slot_np = np.concatenate(py_batch['cas_slot'],
                                         axis=1)  #seqlen, batchsize, slotsize
            cas_continue_go_np = np.concatenate(py_batch['cas_continue_go'],
                                                axis=1)
            cas_act_go_np = np.concatenate(py_batch['cas_act_go'], axis=1)
            cas_slot_go_np = np.concatenate(py_batch['cas_slot_go'], axis=1)
            cas_continue_list_np = np.array(
                py_batch['cas_continue_list']).transpose(
                    (1, 0))  # seqlen, batchsize
            cas_act_list_np = np.array(py_batch['cas_act_list']).transpose(
                (1, 0))  #seqlen, batchsize

            kw_ret['user_len'] = user_len  #batchsize
            kw_ret['last_agent_len'] = last_agent_len  #batchsize
            kw_ret['current_slot_len'] = current_slot_len  #batchsize
            kw_ret[
                'current_user_request_len'] = current_user_request_len  # batchsize
            kw_ret[
                'current_user_inform_len'] = current_user_inform_len  # batchsize
            kw_ret[
                'current_agent_request_len'] = current_agent_request_len  # batchsize
            kw_ret[
                'current_agent_propose_len'] = current_agent_propose_len  # batchsize
            kw_ret['kb_turn'] = cuda_(
                Variable(torch.from_numpy(kb_turn_np).float()),
                self.cfg)  #1, batch_size, kb_turn_size
            kw_ret['last_agent'] = cuda_(
                Variable(torch.from_numpy(last_agent_np).long()),
                self.cfg)  #seqlen, batchsize
            kw_ret['current_slot'] = cuda_(
                Variable(torch.from_numpy(current_slot_np).long()),
                self.cfg)  #seqlen, batchsize
            kw_ret['current_user_request'] = cuda_(
                Variable(torch.from_numpy(current_user_request_np).long()),
                self.cfg)
            kw_ret['current_user_inform'] = cuda_(
                Variable(torch.from_numpy(current_user_inform_np).long()),
                self.cfg)
            kw_ret['current_agent_request'] = cuda_(
                Variable(torch.from_numpy(current_agent_request_np).long()),
                self.cfg)
            kw_ret['current_agent_propose'] = cuda_(
                Variable(torch.from_numpy(current_agent_propose_np).long()),
                self.cfg)
            kw_ret['continue_go'] = cuda_(
                Variable(torch.from_numpy(cas_continue_go_np).float()),
                self.cfg)
            kw_ret['act_go'] = cuda_(
                Variable(torch.from_numpy(cas_act_go_np).float()), self.cfg)
            kw_ret['slot_go'] = cuda_(
                Variable(torch.from_numpy(cas_slot_go_np).float()), self.cfg)
            kw_ret['cas_act'] = cuda_(
                Variable(torch.from_numpy(cas_act_np).float()), self.cfg)
            kw_ret['cas_continue'] = cuda_(
                Variable(torch.from_numpy(cas_continue_np).float()), self.cfg)

            cas_continue_list = cuda_(
                Variable(torch.from_numpy(cas_continue_list_np).long()),
                self.cfg)
            cas_act_list = cuda_(
                Variable(torch.from_numpy(cas_act_list_np).long()), self.cfg)
            cas_slot = cuda_(Variable(torch.from_numpy(cas_slot_np).float()),
                             self.cfg)

            x = cuda_(Variable(torch.from_numpy(user_np).long()),
                      self.cfg)  #seqlen, batchsize
            gt_y = (cas_continue_list, cas_act_list, cas_slot)
        else:
            assert ()
        return x, gt_y, kw_ret
Ejemplo n.º 9
0
    def _convert_batch(self, py_batch, prev_z_py=None):
        kw_ret = {}

        requested_7_np = np.stack(py_batch['requested_7'], axis=0).transpose()
        requested_7_np = requested_7_np[:, :, np.newaxis]  # 7, batchsize, 1
        response_7_np = np.stack(py_batch['response_7'], axis=0).transpose()
        response_7_np = response_7_np[:, :, np.newaxis]  # 7, batchsize, 1
        requestable_key = py_batch['requestable_key']  # (batchsize, 7) keys
        requestable_slot = py_batch['requestable_slot']  # (batchsize, 7) slots
        requestable_key_np = pad_sequences(requestable_key,
                                           len(requestable_key[0]),
                                           padding='post',
                                           truncating='post').transpose((1, 0))
        requestable_slot_np = pad_sequences(requestable_slot,
                                            len(requestable_slot[0]),
                                            padding='post',
                                            truncating='post').transpose(
                                                (1, 0))
        kw_ret['requestable_key_np'] = requestable_key_np
        kw_ret['requestable_slot_np'] = requestable_slot_np
        kw_ret['requestable_key'] = cuda_(
            Variable(torch.from_numpy(requestable_key_np).long()))
        kw_ret['requestable_slot'] = cuda_(
            Variable(torch.from_numpy(requestable_slot_np).long()))
        kw_ret['requested_7'] = cuda_(
            Variable(torch.from_numpy(requested_7_np).float()))
        kw_ret['response_7'] = cuda_(
            Variable(torch.from_numpy(response_7_np).float()))

        u_input_py = py_batch['user']
        u_len_py = py_batch['u_len']

        if cfg.prev_z_method == 'concat' and prev_z_py is not None:
            for i in range(len(u_input_py)):
                eob = self.reader.vocab.encode('EOS_Z2')
                if eob in prev_z_py[i] and prev_z_py[i].index(eob) != len(
                        prev_z_py[i]) - 1:
                    idx = prev_z_py[i].index(eob)
                    u_input_py[i] = prev_z_py[i][:idx + 1] + u_input_py[i]
                else:
                    u_input_py[i] = prev_z_py[i] + u_input_py[i]
                u_len_py[i] = len(u_input_py[i])
                for j, word in enumerate(prev_z_py[i]):
                    if word >= cfg.vocab_size:
                        prev_z_py[i][j] = 2  # unk
        elif cfg.prev_z_method == 'separate' and prev_z_py is not None:
            for i in range(len(prev_z_py)):
                eob = self.reader.vocab.encode('EOS_Z2')
                if eob in prev_z_py[i] and prev_z_py[i].index(eob) != len(
                        prev_z_py[i]) - 1:
                    idx = prev_z_py[i].index(eob)
                    prev_z_py[i] = prev_z_py[i][:idx + 1]
                for j, word in enumerate(prev_z_py[i]):
                    if word >= cfg.vocab_size:
                        prev_z_py[i][j] = 2  # unk
            prev_z_input_np = pad_sequences(prev_z_py,
                                            cfg.max_ts,
                                            padding='post',
                                            truncating='pre').transpose((1, 0))
            prev_z_len = np.array([len(_) for _ in prev_z_py])
            prev_z_input = cuda_(
                Variable(torch.from_numpy(prev_z_input_np).long()))
            kw_ret['prev_z_len'] = prev_z_len
            kw_ret['prev_z_input'] = prev_z_input
            kw_ret['prev_z_input_np'] = prev_z_input_np

        degree_input_np = np.array(py_batch['degree'])
        u_input_np = pad_sequences(u_input_py,
                                   cfg.max_ts,
                                   padding='post',
                                   truncating='pre').transpose((1, 0))
        m_input_np = pad_sequences(py_batch['response'],
                                   cfg.max_ts,
                                   padding='post',
                                   truncating='post').transpose((1, 0))
        r_input_np = pad_sequences(py_batch['requested'],
                                   cfg.req_length,
                                   padding='post',
                                   truncating='post').transpose(
                                       (1, 0))  # (seqlen, batchsize)
        k_input_np = pad_sequences(py_batch['constraint_key'],
                                   len(py_batch['constraint_key'][0]),
                                   padding='post',
                                   truncating='post').transpose((1, 0))
        flat_constraint_value = []
        num_k = k_input_np.shape[0]
        for b in py_batch['constraint_value']:
            for k in b:
                flat_constraint_value.append(k)

        flat_i_input_np = pad_sequences(flat_constraint_value,
                                        cfg.inf_length,
                                        padding='post',
                                        truncating='post')

        i_input_np = []
        i_k_input_np = []
        for idx, k in enumerate(flat_i_input_np):
            i_k_input_np.append(k)
            if (idx + 1) % num_k == 0:
                i_input_np.append(np.asarray(i_k_input_np))
                i_k_input_np = []
        i_input_np = np.asarray(i_input_np)  # (batchsize, key_size, seqlen)

        u_len = np.array(u_len_py)
        m_len = np.array(py_batch['m_len'])

        degree_input = cuda_(
            Variable(torch.from_numpy(degree_input_np).float()))
        u_input = cuda_(Variable(torch.from_numpy(u_input_np).long()))
        m_input = cuda_(Variable(torch.from_numpy(m_input_np).long()))
        r_input = cuda_(Variable(torch.from_numpy(r_input_np).long()))
        k_input = cuda_(Variable(torch.from_numpy(k_input_np).long()))
        i_input = cuda_(Variable(torch.from_numpy(i_input_np).long()))
        i_input = i_input.permute(1, 2, 0)
        z_input = []
        for k_i_input in i_input:
            z_input.append(k_i_input)
        z_input = torch.cat(z_input, dim=0)
        z_input_np = z_input.cpu().data.numpy()

        kw_ret['z_input_np'] = z_input_np

        return u_input, u_input_np, z_input, m_input, m_input_np, u_len, m_len, \
               degree_input, k_input, i_input, r_input, kw_ret, py_batch['constraint_eos']
Ejemplo n.º 10
0
    def interact(self):
        def z2degree(gen_z):
            gen_bspan = self.reader.vocab.sentence_decode(gen_z, eos='EOS_Z2')
            constraint_request = gen_bspan.split()
            constraints = constraint_request[:constraint_request.index('EOS_Z1')] if 'EOS_Z1' \
                in constraint_request else constraint_request
            for j, ent in enumerate(constraints):
                constraints[j] = ent.replace('_', ' ')
            degree = self.reader.db_search(constraints)
            degree_input_list = self.reader._degree_vec_mapping(len(degree))
            degree_input = cuda_(
                Variable(torch.Tensor(degree_input_list).unsqueeze(0)))
            return degree, degree_input

        self.m.eval()
        print('Start interaction.')
        kw_ret = dict({'func': z2degree})
        while True:
            usr = input('usr: '******'END':
                break
            usr_words = usr.split() + ['EOS_U']
            u_len = np.array([len(usr_words)])
            usr_indices = self.reader.vocab.sentence_encode(usr_words)
            u_input_np = np.array(usr_indices)[:, np.newaxis]
            u_input = cuda_(Variable(torch.from_numpy(u_input_np).long()))
            m_idx, z_idx, _ = self.m(mode='test',
                                     degree_input=None,
                                     z_input=None,
                                     u_input=u_input,
                                     u_input_np=u_input_np,
                                     u_len=u_len,
                                     m_input=None,
                                     m_input_np=None,
                                     m_len=None,
                                     turn_states=None,
                                     **kw_ret)
            degree = kw_ret.get('degree')
            venue = random.sample(degree, 1)[0] if degree else dict()
            l = [self.reader.vocab.decode(_) for _ in m_idx[0]]
            if 'EOS_M' in l:
                l = l[:l.index('EOS_M')]
            l_origin = []
            for word in l:
                if 'SLOT' in word:
                    word = word[:-5]
                    if word in venue.keys():
                        value = venue[word]
                        if value != '?':
                            l_origin.append(value.replace(' ', '_'))
                else:
                    l_origin.append(word)
            sys = ' '.join(l_origin)
            print('sys:', sys)
            if cfg.prev_z_method == 'separate':
                eob = self.reader.vocab.encode('EOS_Z2')
                if eob in z_idx[0] and z_idx[0].index(eob) != len(
                        z_idx[0]) - 1:
                    idx = z_idx[0].index(eob)
                    z_idx[0] = z_idx[0][:idx + 1]
                for j, word in enumerate(z_idx[0]):
                    if word >= cfg.vocab_size:
                        z_idx[0][j] = 2  #unk
                prev_z_input_np = pad_sequences(z_idx,
                                                cfg.max_ts,
                                                padding='post',
                                                truncating='pre').transpose(
                                                    (1, 0))
                prev_z_len = np.array([len(_) for _ in z_idx])
                prev_z_input = cuda_(
                    Variable(torch.from_numpy(prev_z_input_np).long()))
                kw_ret['prev_z_len'] = prev_z_len
                kw_ret['prev_z_input'] = prev_z_input
                kw_ret['prev_z_input_np'] = prev_z_input_np