def data_info(utterance, memory, cuda): lis = process_sent(utterance) if len(lis) == 0: raise Error("Input utterance can not be empty string") word2idx = memory['enc2idx'] ids = [word2idx[w] if w in word2idx else Constants.UNK for w in lis] data = torch.tensor(ids).view(1, -1) word2idx = memory['dec2idx'] ids, oov_list = seq2extend_ids(lis, word2idx) enc_batch_extend_vocab_idx = torch.tensor(ids).view(1, -1) if len(oov_list) == 0: extra_zeros = None else: extra_zeros = torch.zeros((1, len(oov_list))) if cuda: data = data.cuda() enc_batch_extend_vocab_idx = enc_batch_extend_vocab_idx.cuda() if extra_zeros is not None: extra_zeros = extra_zeros.cuda() return data, None, extra_zeros, enc_batch_extend_vocab_idx, oov_list
def read_file(filename): with codecs.open(filename, 'r') as f: lines = f.readlines() lines = [line.split('\t<=>\t') for line in lines] datas = [] for line in lines: sent_lis = process_sent(line[0]) if len(sent_lis) == 0: continue class_string = line[1] if class_string.strip() == '': continue classes = class_string.strip().split(';') classes = [string for string in classes if len(string.strip().split('-')) >= 2] classes = sorted(classes) if len(classes) == 0: continue pre_act = classes[0].strip().split('-')[0] tmp = [] for string in classes: act = string.strip().split('-')[0] if act == pre_act: tmp.append(string) else: class_string = ';'.join(tmp) datas.append((line[0], class_string)) tmp = [string] if len(tmp) != 0: class_string = ';'.join(tmp) datas.append((line[0], class_string)) return datas
def judge_utt_label(utterance, class_string, memory, cuda): origin_utt = utterance classes = class_string.strip().split(';') classes = [cls.strip().split('-') for cls in classes] values = [] for cls in classes: if len(cls) == 3: if cls[1] in ['food', 'name', 'area', 'near']: values.extend(cls[2].strip().split()) if len(values) > 0: num = max(int(len(values) / 2), 1) values = random.sample(values, num) for value in values: utterance = utterance.replace(value, 'pad') if utterance != origin_utt: lis = process_sent(utterance) word2idx = memory['enc2idx'] ids = [ word2idx[w] if w in word2idx else Constants.UNK for w in lis ] data = torch.tensor(ids).view(1, -1) if cuda: data = data.cuda() return data return None
def test(opt): opt.experiment = os.path.join(root_dir, opt.experiment) opt.load_chkpt = os.path.join(opt.experiment, opt.load_chkpt) opt.save_decode = os.path.join(opt.experiment, opt.save_decode) opt.test_json = os.path.join(opt.data_root, opt.test_json) idx2class = {v:k for k,v in opt.class2idx.items()} model = make_model(opt) chkpt = torch.load(opt.load_chkpt, map_location=lambda storage, log: storage) model.load_state_dict(chkpt) # ======================================= model.eval() # ======================================= sessions = json.loads(open(opt.test_json).read())['sessions'] print('Decoding ...') decode_sessions = {'sessions': []} for session in sessions: n_session = {} n_session['session-id'] = session['session-id'] n_session['turns'] = [] for turn in session['turns']: asr_hyps = turn['asr-hyps'] sent = asr_hyps[0]['asr-hyp'] tokens = process_sent(sent) if len(tokens) == 0: slu_hyp = [] else: sent_ids = [opt.word2idx.get(w) if w in opt.word2idx else Constants.UNK for w in tokens] datas = torch.from_numpy(np.asarray(sent_ids, dtype='int64')).view(1, -1) if opt.cuda: datas = datas.cuda() probs = model(datas, None) scores = probs.data.cpu().view(-1,).numpy() pred_classes = [i for i,p in enumerate(scores) if p > 0.5] classes = [idx2class[i] for i in pred_classes] slu_hyp = [slot2dic(string) for string in classes] n_session['turns'].append( { 'asr-hyps': asr_hyps, 'slu-hyps': [{'slu-hyp': slu_hyp, 'score': 1.0}] } ) decode_sessions['sessions'].append(n_session) string = json.dumps(decode_sessions, sort_keys=True, indent=4, separators=(',', ':')) with open(opt.save_decode, 'w') as f: f.write(string) print('Decode results saved in {}'.format(opt.save_decode))
def read_file(filename): with codecs.open(filename, 'r') as f: lines = f.readlines() lines = [line.split('\t<=>\t') for line in lines] datas = [] for line in lines: sent_lis = process_sent(line[0]) if len(sent_lis) > 0: datas.append(line) return datas
def data_info(utterance, memory, cuda): lis = process_sent(utterance) if len(lis) == 0: raise Error("Input utterance can not be empty string") word2idx = memory['enc2idx'] ids = [word2idx[w] if w in word2idx else Constants.UNK for w in lis] data = torch.tensor(ids).view(1, -1) if cuda: data = data.cuda() return data, None
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
def decode_act(model, utterance, memory, cuda): sent_lis = process_sent(utterance) if len(sent_lis) == 0: return [] data, lengths = ActDataset.data_info(utterance, memory, 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) ## 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] acts = [memory['idx2act'][i] for i in pred_acts] return acts
def decode_slot(model, utterance, class_string, memory, cuda): sent_lis = process_sent(utterance) if len(sent_lis) == 0: return [] data, lengths = SlotDataset.data_info(utterance, memory, cuda) act_inputs, slot_label = SlotDataset.label_info(class_string, memory, 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) ## slot prediction slot_scores = model.slot_predict(h_T, act_inputs) slot_scores = slot_scores.data.cpu().view(-1,).numpy() pred_slots = [i for i,p in enumerate(slot_scores) if p > 0.5] slots = [memory['idx2slot'][i] for i in pred_slots] return slots
def read_file(filename): with codecs.open(filename, 'r') as f: lines = f.readlines() lines = [line.split('\t<=>\t') for line in lines] datas = [] for line in lines: sent_lis = process_sent(line[0]) if len(sent_lis) == 0: continue class_string = line[1] if class_string.strip() == '': continue classes = class_string.strip().split(';') for string in classes: num = len(string.strip().split('-', 2)) if num >= 3: datas.append((line[0], string)) # This is addition for debugging # break # ============================== return datas
def decode_slu(model, utterance, memory, cuda): sent_lis = process_sent(utterance) if len(sent_lis) == 0: return [] data, lengths, extra_zeros, enc_batch_extend_vocab_idx, oov_list = \ SLUDataset.data_info(utterance, memory, cuda) act_slot_values = [] # Model processing ## encoder outputs, hiddens = model.encoder(data, lengths) h_T = hiddens[0].transpose(0, 1).contiguous().view(-1, model.enc_hid_all_dim) ## 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) print(values) slot = act_slot[1][1] values = correct_value(slot, values) print(slot) print(values) input() act_slot_values.append('-'.join(list(act_slot[1]) + [values])) return act_slot_values