Ejemplo n.º 1
0
    def valid_on_epoch(self, epoch, filename, memory):

        self.logger.info("Epoch {:02} {} begins validing ...................".format(epoch, self.tag))

        self.model.eval()

        start_time = time.time()
        score = Fscore(self.tag)

        datas = SLUDataset.read_file(filename, memory)

        for pair in datas:

            cnet = pair['cnet']
            class_string = pair['label']

            gold_classes = SLUDataset.class_info(class_string)
            pred_classes = decode_slu(self.model, cnet, memory, self.cuda)

            score.update_tp_fp_fn(pred_classes, gold_classes)

        fscore = score.output_fscore(self.logger, epoch)

        elapsed_time = time.time() - start_time
        self.logger.info("Epoch {:02} {} ends validing elapsed_time: {:6.0f}s".format(
            epoch, self.tag, elapsed_time)
        )
        self.logger.info('*****************************************************')

        return fscore
Ejemplo n.º 2
0
def error(opt):

    opt.experiment = os.path.join(root_dir, opt.experiment)
    opt.load_chkpt = os.path.join(opt.experiment, opt.save_model)
    opt.test_file = os.path.join(opt.data_root, opt.test_file)
    opt.save_file = os.path.join(opt.experiment, 'error.json')

    # Model loading
    model = make_model(opt)
    chkpt = torch.load(opt.load_chkpt,
                       map_location=lambda storage, log: storage)
    model.load_state_dict(chkpt)
    if opt.deviceid >= 0:
        model = model.cuda()
    print(model)
    # ====== *********************** ================
    model.eval()
    # ===============================================

    # decode
    print('Decoding ...')
    if opt.task == 'act':
        datas = ActDataset.read_file(opt.test_file, opt.memory)
    elif opt.task == 'slot':
        datas = SlotDataset.read_file(opt.test_file, opt.memory)
    elif opt.task == 'value':
        datas = ValueDataset.read_file(opt.test_file, opt.memory)
    elif opt.task == 'slu':
        datas = SLUDataset.read_file(opt.test_file, opt.memory)

    dic = {'pairs': []}
    for pair in datas:
        cnet = pair['cnet']
        class_string = pair['label']
        if opt.task == 'act':
            gold_classes = ActDataset.class_info(class_string)
            pred_classes = decode_act(model, cnet, opt.memory, opt.cuda)
        elif opt.task == 'slot':
            gold_classes = SlotDataset.class_info(class_string)
            pred_classes = decode_slot(model, cnet, class_string, opt.memory,
                                       opt.cuda)
        elif opt.task == 'value':
            gold_classes = ValueDataset.class_info(class_string)
            pred_classes = decode_value(model, cnet, class_string, opt.memory,
                                        opt.cuda)
        elif opt.task == 'slu':
            gold_classes = SLUDataset.class_info(class_string)
            pred_classes = decode_slu(model, cnet, opt.memory, opt.cuda)
        gold_class = ';'.join(sorted(gold_classes))
        pred_class = ';'.join(sorted(pred_classes))
        if gold_class != pred_class:
            pr = {'cnet': cnet, 'label': gold_class, 'pred': pred_class}
            dic['pairs'].append(pr)

    string = json.dumps(dic, sort_keys=True, indent=4, separators=(',', ';'))
    with open(opt.save_file, 'w') as f:
        f.write(string)
    print('Decode results saved in {}'.format(opt.save_file))
Ejemplo n.º 3
0
def error(opt):

    opt.experiment = os.path.join(root_dir, opt.experiment)
    opt.load_chkpt = os.path.join(opt.experiment, opt.save_model)
    opt.test_file = os.path.join(opt.data_root, opt.test_file)
    opt.save_file = os.path.join(opt.experiment, 'error.info')

    # Model loading
    model = make_model(opt)
    chkpt = torch.load(opt.load_chkpt,
                       map_location=lambda storage, log: storage)
    model.load_state_dict(chkpt)
    if opt.deviceid >= 0:
        model = model.cuda()
    print(model)
    # ====== *********************** ================
    model.eval()
    # ===============================================

    # decode
    print('Decoding ...')
    g = open(opt.save_file, 'w')
    if opt.task == 'act':
        lines = ActDataset.read_file(opt.test_file)
    elif opt.task == 'slot':
        lines = SlotDataset.read_file(opt.test_file)
    elif opt.task == 'value':
        lines = ValueDataset.read_file(opt.test_file)
    elif opt.task == 'slu':
        lines = SLUDataset.read_file(opt.test_file)

    for (utterance, class_string) in lines:
        if opt.task == 'act':
            gold_classes = ActDataset.class_info(class_string)
            pred_classes = decode_act(model, utterance, opt.memory, opt.cuda)
        elif opt.task == 'slot':
            gold_classes = SlotDataset.class_info(class_string)
            pred_classes = decode_slot(model, utterance, class_string,
                                       opt.memory, opt.cuda)
        elif opt.task == 'value':
            gold_classes = ValueDataset.class_info(class_string)
            pred_classes = decode_value(model, utterance, class_string,
                                        opt.memory, opt.cuda)
        elif opt.task == 'slu':
            gold_classes = SLUDataset.class_info(class_string)
            pred_classes = decode_slu(model, utterance, opt.memory, opt.cuda)
        gold_class = ';'.join(sorted(gold_classes))
        pred_class = ';'.join(sorted(pred_classes))
        if gold_class != pred_class:
            g.write('{}\t<=>\t{}\t<=>\t{}\n'.format(utterance, gold_class,
                                                    pred_class))
    g.close()
    print('Decode results saved in {}'.format(opt.save_file))
Ejemplo n.º 4
0
def decode_slu(model, cnet, memory, cuda):

    result = process_cn_example(cnet, memory['enc2idx'])

    if result is None:
        return []

    data, lengths, extra_zeros, enc_batch_extend_vocab_idx, oov_list = \
            SLUDataset.data_info(cnet, memory, cuda)

    act_slot_values = []

    # Model processing

    ## encoder
    outputs, hiddens = model.encoder(data, lengths)
    h_T = hiddens[0]

    ## act prediction
    act_scores = model.act_stc(h_T)
    act_scores = act_scores.data.cpu().view(-1, ).numpy()
    pred_acts = [i for i, p in enumerate(act_scores) if p > 0.5]
    act_pairs = [(i, memory['idx2act'][i]) for i in pred_acts]
    remain_acts = []
    for act in act_pairs:
        if act[1] == 'pad':
            continue
        elif act[1] in memory['single_acts']:
            act_slot_values.append(act[1])
        else:
            remain_acts.append(act)

    if len(remain_acts) == 0:
        return act_slot_values

    ## slot prediction
    remain_act_slots = []
    for act in remain_acts:
        act_input = torch.tensor([act[0]]).view(1, 1)
        if cuda:
            act_input = act_input.cuda()
        slot_scores = model.slot_predict(h_T, act_input)
        slot_scores = slot_scores.data.cpu().view(-1, ).numpy()
        pred_slots = [i for i, p in enumerate(slot_scores) if p > 0.5]
        slot_pairs = [(i, memory['idx2slot'][i]) for i in pred_slots]
        if act[1] in memory['double_acts']:
            for slot in slot_pairs:
                act_slot_values.append('-'.join([act[1], slot[1]]))
        else:
            for slot in slot_pairs:
                if slot[1] != 'pad':
                    remain_act_slots.append(list(zip(act, slot)))

    if len(remain_act_slots) == 0:
        return act_slot_values

    ## value decoder
    s_decoder = model.enc_to_dec(hiddens)
    for act_slot in remain_act_slots:
        s_t_1 = s_decoder
        act_slot_ids = torch.tensor(act_slot[0]).view(1, 2)
        y_t = torch.tensor([Constants.BOS]).view(1, 1)
        if cuda:
            y_t = y_t.cuda()
            act_slot_ids = act_slot_ids.cuda()
        value_ids = beam_search(model.value_decoder, act_slot_ids, extra_zeros,
                                enc_batch_extend_vocab_idx, s_decoder, outputs,
                                lengths, len(memory['dec2idx']), cuda)[1:-1]
        value_lis = []
        for vid in value_ids:
            if vid < len(memory['idx2dec']):
                value_lis.append(memory['idx2dec'][vid])
            else:
                value_lis.append(oov_list[vid - len(memory['idx2dec'])])
        values = ' '.join(value_lis)
        act_slot_values.append('-'.join(list(act_slot[1]) + [values]))

    return act_slot_values
Ejemplo n.º 5
0
def train(opt):

    opt.experiment = os.path.join(root_dir, opt.experiment)
    if not os.path.exists(opt.experiment):
        os.makedirs(opt.experiment)

    opt.save_model = os.path.join(opt.experiment, opt.save_model)
    opt.log_path = os.path.join(opt.experiment, 'log.train')
    opt.logger = make_logger(opt.log_path)

    # memory info
    print("encoder word2idx number: {}".format(opt.enc_word_vocab_size))
    print("decoder word2idx number: {}".format(opt.dec_word_vocab_size))
    print("act2idx number: {}".format(opt.act_vocab_size))
    print("slot2idx number: {}".format(opt.slot_vocab_size))

    # Model definition
    model = make_model(opt)
    if opt.load_word_emb:
        emb = read_emb(opt.memory['enc2idx'])
        model.enc_word_emb.init_weight_from_pre_emb(emb, opt.fix_word_emb)
    if opt.load_class_emb:
        emb = opt.memory['act_emb']
        model.act_emb.init_weight_from_pre_emb(emb, opt.fix_class_emb)
        emb = opt.memory['slot_emb']
        model.slot_emb.init_weight_from_pre_emb(emb, opt.fix_class_emb)
    if opt.share_param:
        #model.value_decoder.outlin.weight.data = model.word_emb.embedding.weight.data
        #model.value_decoder.outlin.weight.requires_grad = model.word_emb.embedding.weight.requires_grad
        model.act_stc.lin.weight.data = model.act_emb.embedding.weight.data
        model.act_stc.lin.weight.requires_grad = model.act_emb.embedding.weight.requires_grad
        model.slot_stc.lin.weight.data = model.slot_emb.embedding.weight.data
        model.slot_stc.lin.weight.requires_grad = model.slot_emb.embedding.weight.requires_grad
    if opt.cuda:
        model = model.cuda()
    print(model)

    # optimizer details
    optimizer = Optim(opt.optim, opt.lr, max_grad_norm=opt.max_norm)
    optimizer.set_parameters(model.named_parameters())
    print("training parameters number: {}".format(len(optimizer.params)))

    # loss definition
    #stc_criterion = MaskedBCELoss(opt.cuda)
    stc_criterion = nn.BCELoss(reduction='sum')
    nll_criterion = nn.NLLLoss(reduction='sum')
    if opt.cuda:
        stc_criterion = stc_criterion.cuda()
        nll_criterion = nll_criterion.cuda()

    # training procedure
    if opt.task == 'slu':
        data_iter = SLUDataset(opt.data_root + 'train', opt.memory, opt.cuda,
                               True)
        trainer = SLUTrainer(model, (stc_criterion, nll_criterion),
                             optimizer,
                             opt.logger,
                             cuda=opt.cuda)
    elif opt.task == 'act':
        data_iter = ActDataset(opt.data_root + 'train', opt.memory, opt.cuda,
                               True)
        trainer = ActTrainer(model,
                             stc_criterion,
                             optimizer,
                             opt.logger,
                             cuda=opt.cuda)
    elif opt.task == 'slot':
        data_iter = SlotDataset(opt.data_root + 'train', opt.memory, opt.cuda,
                                True)
        trainer = SlotTrainer(model,
                              stc_criterion,
                              optimizer,
                              opt.logger,
                              cuda=opt.cuda)
    elif opt.task == 'value':
        data_iter = ValueDataset(opt.data_root + 'train', opt.memory, opt.cuda,
                                 True)
        trainer = ValueTrainer(model,
                               nll_criterion,
                               optimizer,
                               opt.logger,
                               cuda=opt.cuda)

    trainer.train(opt.epochs, opt.batch_size, opt.memory, data_iter,
                  opt.data_root + 'valid', opt.save_model)