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
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))
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))
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
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)