예제 #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 = ValueDataset.read_file(filename, memory)

        for pair in datas:
            
            cnet = pair['cnet']
            class_string = pair['label']

            gold_classes = ValueDataset.class_info(class_string)
            pred_classes = decode_value(self.model, cnet, class_string, 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} {} end validing elapsed_time: {:6.0f}s".format(
            epoch, self.tag, elapsed_time)
        )
        self.logger.info('*****************************************************')

        return fscore
예제 #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))
예제 #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))
예제 #4
0
def decode_value(model, utterance, class_string, memory, cuda):

    sent_lis = process_sent(utterance)
    if len(sent_lis) == 0:
        return []

    data, lengths, extra_zeros, enc_batch_extend_vocab_idx, oov_list = \
            ValueDataset.data_info(utterance, memory, cuda)
    act_inputs, act_slot_pairs, values_inp, values_out = \
            ValueDataset.label_info(class_string, memory, oov_list, cuda)

    # Model processing
    ## encoder
    outputs, hiddens = model.encoder(data, lengths)
    h_T = hiddens[0].transpose(0, 1).contiguous().view(-1, model.enc_hid_all_dim)

    ## value decoder
    s_decoder = model.enc_to_dec(hiddens)
    s_t_1 = s_decoder
    act_slot_ids = act_slot_pairs[0]
    y_t = torch.tensor([Constants.BOS]).view(1, 1)
    if cuda:
        y_t = y_t.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)]

    slot = memory['idx2slot'][act_slot_pairs[0][0,1].item()]
    value = correct_value(slot, values[0])

    if value is None:
        return []

    values = [value]

    return values
예제 #5
0
def decode_value(model, cnet, class_string, 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 = \
            ValueDataset.data_info(cnet, memory, cuda)
    act_inputs, act_slot_pairs, values_inp, values_out = \
            ValueDataset.label_info(class_string, memory, oov_list, cuda)

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

    ## value decoder
    s_decoder = model.enc_to_dec(hiddens)
    s_t_1 = s_decoder
    act_slot_ids = act_slot_pairs[0]
    y_t = torch.tensor([Constants.BOS]).view(1, 1)
    if cuda:
        y_t = y_t.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)]

    return values
예제 #6
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)