├── resources ├── TextCNN.JPG ├── JOINT_MODEL.JPG ├── slot_filling_alime.JPG ├── Attention-Based Recurrent Neural Network Models for Joint Intent Detection and Slot Filling.zip ├── a1_generate_training_data.py ├── a1_generate_raw_data_single.py └── a1_test.py ├── knowledge └── slot_values.txt ├── joint_model_knowl_v6_with_domain_knowledge ├── a1_generate_knowledges.py ├── joint_intent_slots_knowledge_domain_train.py └── joint_intent_slots_knowledge_domain_predict.py ├── joint_model_knowl_v8_slot_condition_intent ├── a1_generate_knowledges.py ├── joint_intent_slots_knowledge_conditional_train.py └── joint_intent_slots_knowledge_conditional_predict.py ├── joint_model_knowl_v7_with_domain_knowledge_context_window ├── a1_generate_knowledges.py ├── joint_intent_slots_knowledge_domain_train.py └── joint_intent_slots_knowledge_domain_predict.py ├── joint_model_naive_v1 ├── joint_intent_slots_navie_predict.py └── joint_intent_slots_naive_train.py ├── README.md ├── joint_model_knowl_v0 ├── a1_joint_intent_slots_predict.py └── a1_joint_intent_slots_train.py ├── joint_model_knowl_v2_simpl_modl_feat ├── joint_intent_slots_knowledge_predict.py └── joint_intent_slots_knowledge_train.py ├── joint_model_knowl_v5_without_knowledge ├── joint_intent_slots_knowledge_train.py └── joint_intent_slots_knowledge_predict.py ├── joint_model_knowl_v3_bi_directional_cnn_tmall ├── joint_intent_slots_knowledge_train.py └── joint_intent_slots_knowledge_predict.py └── joint_model_knowl_v4_cnn_with_symbol_alime ├── joint_intent_slots_knowledge_train.py └── joint_intent_slots_knowledge_predict.py /resources/TextCNN.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brightmart/slot_filling_intent_joint_model/HEAD/resources/TextCNN.JPG -------------------------------------------------------------------------------- /resources/JOINT_MODEL.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brightmart/slot_filling_intent_joint_model/HEAD/resources/JOINT_MODEL.JPG -------------------------------------------------------------------------------- /resources/slot_filling_alime.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brightmart/slot_filling_intent_joint_model/HEAD/resources/slot_filling_alime.JPG -------------------------------------------------------------------------------- /resources/Attention-Based Recurrent Neural Network Models for Joint Intent Detection and Slot Filling.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brightmart/slot_filling_intent_joint_model/HEAD/resources/Attention-Based Recurrent Neural Network Models for Joint Intent Detection and Slot Filling.zip -------------------------------------------------------------------------------- /resources/a1_generate_training_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | import codecs 4 | from a1_generate_raw_data_single import generate_raw_data_singel 5 | 6 | test_mode=True 7 | def generate_raw_data(source_file_name): 8 | #1.read file 9 | source_file_object=codecs.open(source_file_name,'r','utf-8') 10 | lines=source_file_object.readlines() 11 | #2.loop each line, and add data to list. 12 | result_dict={} 13 | for i,line in enumerate(lines): 14 | sub_dict=generate_raw_data_singel(line) 15 | if sub_dict is not None and sub_dict['user'] is not None: 16 | result_dict[sub_dict['user']]=sub_dict 17 | 18 | # print to have a look 19 | print("length of result list:",len(result_dict)) 20 | i=0 21 | return result_dict 22 | 23 | #source_file_name='knowledge/sht_20171125.txt' 24 | #generate_raw_data(source_file_name) -------------------------------------------------------------------------------- /resources/a1_generate_raw_data_single.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | def generate_raw_data_singel(sline): 5 | try: 6 | myjson=json.loads(sline) 7 | except: 8 | print(sline) 9 | return None 10 | result={} 11 | elements=myjson['actions'] 12 | for i,element in enumerate(elements): 13 | target=element['target'] 14 | actor = element['actor'] 15 | intent = element['intent'] 16 | if 'speech' in element: speech=element['speech'] 17 | slots = element['slots'] 18 | 19 | if actor=='u' and target=='a': 20 | result['user']=speech 21 | if actor=='a' and target=='s': 22 | result['intent']=intent 23 | #print("slots:",slots) 24 | slot_dict={} 25 | for i,element in enumerate(slots): 26 | slot_dict[element['name']]=element['value'] 27 | result['slots']=slot_dict 28 | return result 29 | 30 | 31 | 32 | #sline='{"dialog_template_id": "关设备_范围_成功__2c9081a45ff32c08015ff339cfe10045", "actions": [{"speech": "帮忙关闭一下一同的彩色灯泡吧", "actor": "u", "intent": "用户关设备<全部范围><设备名>", "target": "a", "slots": [{"name": "全部范围", "svd_name": "shared/全部范围", "value": "一同", "start": 6}, {"name": "设备名", "svd_name": "shared/设备名", "value": "彩色灯泡", "start": 9}]}, {"actor": "a", "intent": "关设备<全部范围><设备名>", "target": "s", "slots": [{"name": "全部范围", "value": "一同"}, {"name": "设备名", "value": "彩色灯泡"}]}, {"actor": "s", "intent": "关设备<全部范围><设备名>的应答", "target": "a", "slots": [{"name": "状态", "svd_name": "状态1", "value": "成功"}]}, {"speech": "控制成功", "actor": "a", "intent": "控制成功确认", "target": "u", "slots": []}]}' 33 | #result=generate_raw_data_singel(sline) 34 | #print(result) 35 | -------------------------------------------------------------------------------- /resources/a1_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import jieba 3 | import codecs 4 | from a1_data_util import generate_raw_data 5 | 6 | slot_values_file='knowledge_all/slot_values.txt' 7 | 8 | #jieba.load_userdict(slot_values_file) 9 | def test_jieba(string): 10 | result=jieba.lcut(string) 11 | return result 12 | 13 | string='帮我打个从梦想小镇出发到青山湖的快车' #'帮忙关一下主卧所有的挂烫机' #'主卧机顶盒和玄关吸尘器为我关个' #我要关闭壁橱灯''替我关闭一下车库全部的自定义面板' #'帮忙关闭一下一同的彩色灯泡空气炸锅吧' 14 | result=test_jieba(string) #替', '我', '关闭', '一下', '车库', '全部', '的', '自定义面板' 15 | print("result:",result) 16 | 17 | 18 | 19 | def tokenize_sentence(sentence): 20 | """tokenize sentence""" 21 | #sentence=sentence.strip() 22 | result_list=None 23 | try: 24 | result_list=jieba.lcut(sentence) 25 | except: 26 | print("tokenize_sentence.error:",sentence) 27 | return result_list 28 | 29 | def average_length_user_speech(file): 30 | #file_object=codecs.open(file,'r','utf-8') 31 | #lines=file_object.readlines() 32 | #data_source = 'knowledge/sht_20171125.txt' 33 | data_dict = generate_raw_data(file) 34 | sentence_user_speech_list = list(data_dict.keys()) 35 | dict_length={5:0,10:0,15:0,20:0,25:0} 36 | sum_length=0 37 | number_line=len(sentence_user_speech_list) 38 | for i,line in enumerate(sentence_user_speech_list): 39 | listt=tokenize_sentence(line.strip()) 40 | listt_length=len(listt) 41 | sum_length+=listt_length 42 | if listt_length<=5: 43 | dict_length[5]=dict_length[5]+1 44 | elif listt_length<=10: 45 | dict_length[10] = dict_length[10] + 1 46 | elif listt_length<=15: 47 | dict_length[15] = dict_length[15] + 1 48 | elif listt_length<=20: 49 | dict_length[20] = dict_length[20] + 1 50 | else: 51 | dict_length[25] = dict_length[25] + 1 52 | print("dict_length:",dict_length,";average_length:",float(sum_length)/float(number_line)) 53 | #file_object.close() 54 | 55 | 56 | #file='knowledge/sht_20171125.txt' 57 | #file='knowledge_skill3/skill3_train_20171114.txt' #('dict_length:', {25: 4614, 10: 178096, 20: 21270, 5: 41632, 15: 48436}, ';average_length:', 8.973320682337578) 58 | #average_length_user_speech(file) #{25: 0, 10: 37632, 20: 50, 5: 16872, 15: 2755}-->{ 10: 37632, 5: 16872, 15: 2755}--->avg:6.6438081278682235 59 | 60 | 61 | import time 62 | def sayhello(str): 63 | print("Hello ",str) 64 | time.sleep(2) 65 | 66 | #name_list =['xiaozi','aa','bb','cc'] 67 | #start_time = time.time() 68 | #for i in range(len(name_list)): 69 | # sayhello(name_list[i]) 70 | #print ('%d second'% (time.time()-start_time)) 71 | 72 | 73 | import threadpool 74 | def sayhello(str): 75 | print ("Hello ",str) 76 | time.sleep(2) 77 | 78 | #name_list =['xiaozi','aa','bb','cc'] #start_time = time.time() 79 | #pool = threadpool.ThreadPool(10) 80 | #requests = threadpool.makeRequests(sayhello, name_list) 81 | #[pool.putRequest(req) for req in requests] 82 | #pool.wait() #print ('%d second'% (time.time()-start_time)) 83 | -------------------------------------------------------------------------------- /knowledge/slot_values.txt: -------------------------------------------------------------------------------- 1 | 饮水机 2000 2 | 彩光灯泡 2000 3 | 日光灯 2000 4 | 总共 2000 5 | LED灯带 2000 6 | 冷柜 2000 7 | 卧室 2000 8 | 无线开关 2000 9 | 墙壁插座 2000 10 | 客卧 2000 11 | 都 2000 12 | 门厅 2000 13 | 调速开关 2000 14 | 一共 2000 15 | 入户门 2000 16 | 空气净化器 2000 17 | 床灯 2000 18 | TC 23路开关 2000 19 | 珠帘 2000 20 | TC 32路开关 2000 21 | 照明灯 2000 22 | 落地台灯 2000 23 | 储藏室 2000 24 | TC 13路开关 2000 25 | 智能台灯 2000 26 | 双控开关 2000 27 | 鱼线吊灯 2000 28 | SP Mini 2000 29 | 电视机 2000 30 | 四控开关 2000 31 | 应急灯 2000 32 | 排插 2000 33 | 除湿机 2000 34 | 卡通台灯 2000 35 | 灯饰 2000 36 | 会计室 2000 37 | 过道 2000 38 | 枝型吊灯 2000 39 | Wifi插座 2000 40 | 挂烫机 2000 41 | 彩灯 2000 42 | 整个 2000 43 | 燃气灶 2000 44 | 智能开关 2000 45 | 床头灯 2000 46 | 墙壁WiFi插座 2000 47 | 浴室 2000 48 | 筒灯 2000 49 | 电视 2000 50 | 探照灯 2000 51 | 装饰夜灯 2000 52 | 风扇 2000 53 | 单开开关 2000 54 | 客厅 2000 55 | 控制室 2000 56 | 滚筒 2000 57 | 起居室 2000 58 | 中央空调 2000 59 | 风扇吊灯 2000 60 | 会议室 2000 61 | 门廊 2000 62 | 阳台 2000 63 | 台灯 2000 64 | 色温灯 2000 65 | 门口 2000 66 | 客房 2000 67 | 次卧 2000 68 | 调光灯 2000 69 | TC 33路开关 2000 70 | 衣柜间 2000 71 | 卷帘 2000 72 | 玄关 2000 73 | TC 31路开关 2000 74 | 电压力锅 2000 75 | LED小夜灯 2000 76 | 扫地机器人 2000 77 | 月光盒 2000 78 | 主卧 2000 79 | 咖啡机 2000 80 | LED灯 2000 81 | LED彩光灯泡 2000 82 | 双开开关 2000 83 | 入墙插座 2000 84 | 接待处 2000 85 | 环境检测仪 2000 86 | 统统 2000 87 | 油烟机 2000 88 | 冰箱 2000 89 | 射灯 2000 90 | LED吸顶灯 2000 91 | 空气开关 2000 92 | 三控开关 2000 93 | 厕所 2000 94 | 百叶窗帘 2000 95 | LED台灯 2000 96 | 彩光灯带 2000 97 | 净水器 2000 98 | 一齐 2000 99 | 智能插座 2000 100 | TC 21路开关 2000 101 | 阁楼 2000 102 | 吸尘器 2000 103 | 煮蛋器 2000 104 | 一楼 2000 105 | 小冰箱 2000 106 | 智能灯 2000 107 | SP Mini2 2000 108 | 壁扇 2000 109 | 夜灯 2000 110 | 储物室 2000 111 | 柜式空调 2000 112 | 壁柜灯 2000 113 | 电磁炉 2000 114 | 工长室 2000 115 | 面包机 2000 116 | 储物间 2000 117 | 嵌入式厨电 2000 118 | 壁橱灯 2000 119 | 彩光灯 2000 120 | 主人房 2000 121 | 主灯 2000 122 | 彩色灯带 2000 123 | 天台 2000 124 | 书房 2000 125 | 流光开关 2000 126 | 装饰灯 2000 127 | 装饰台灯 2000 128 | 触摸开关 2000 129 | LED灯泡 2000 130 | 豆浆机 2000 131 | 微波炉 2000 132 | 后花园 2000 133 | 洗碗机 2000 134 | 三开开关 2000 135 | 挂式空调 2000 136 | 前花园 2000 137 | 节能灯 2000 138 | 白炽灯 2000 139 | 房间 2000 140 | 镜前灯 2000 141 | 遥控开关 2000 142 | 荧光灯 2000 143 | 智能灯具 2000 144 | 幻彩灯带 2000 145 | 灯 2000 146 | 电烤箱 2000 147 | 门厅灯 2000 148 | 制冷风扇 2000 149 | 洗手间 2000 150 | 二楼 2000 151 | 电饭煲 2000 152 | TC 22路开关 2000 153 | 香薰仪 2000 154 | 触摸入墙开关 2000 155 | 加湿器 2000 156 | 车库 2000 157 | 一起 2000 158 | 彩色灯 2000 159 | 调光开关 2000 160 | 灯带 2000 161 | 门铃开关 2000 162 | 一切 2000 163 | 开关 2000 164 | 节能灯泡 2000 165 | LED射灯 2000 166 | 台扇 2000 167 | 彩色灯泡 2000 168 | 落地灯 2000 169 | TC 11路开关 2000 170 | 卫生间 2000 171 | 一同 2000 172 | wc 2000 173 | 共同 2000 174 | 灯泡 2000 175 | 百叶帘 2000 176 | 墙壁开关 2000 177 | 榨汁机 2000 178 | 走廊 2000 179 | 洗衣机 2000 180 | 床头的灯 2000 181 | 窗帘 2000 182 | 全数 2000 183 | 沐浴房 2000 184 | 庭院灯 2000 185 | Wifi定时插座 2000 186 | 灯具 2000 187 | 手电筒 2000 188 | 空调 2000 189 | 吊扇 2000 190 | 音响 2000 191 | 落地暖灯 2000 192 | TC 12路开关 2000 193 | 音箱 2000 194 | 挂机 2000 195 | 小夜灯 2000 196 | 完全 2000 197 | wifi设备 2000 198 | 安防摄像头 2000 199 | 花园 2000 200 | 四开开关 2000 201 | 多控开关 2000 202 | 节能led灯 2000 203 | 主卫 2000 204 | 插座 2000 205 | 热水器 2000 206 | 电水壶 2000 207 | 吊灯 2000 208 | 电蒸炉 2000 209 | 智能灯带 2000 210 | 干衣机 2000 211 | 全面 2000 212 | 消毒柜 2000 213 | 氛围照明 2000 214 | LED落地灯 2000 215 | 经理室 2000 216 | LED镜前灯 2000 217 | 休息室 2000 218 | 小台扇 2000 219 | 客人房 2000 220 | 排气扇 2000 221 | 自定义面板 2000 222 | 脱水机 2000 223 | 柜机 2000 224 | 淋浴间 2000 225 | LED智能台灯 2000 226 | USB风扇 2000 227 | 水晶灯 2000 228 | 全部 2000 229 | 壁灯 2000 230 | 安防套件 2000 231 | 单控开关 2000 232 | 门 2000 233 | 全 2000 234 | 化验室 2000 235 | 全体 2000 236 | 更衣室 2000 237 | 阅读台灯 2000 238 | 落地风扇 2000 239 | 装饰带 2000 240 | 监控器 2000 241 | 餐厅 2000 242 | 室外灯 2000 243 | 厨房 2000 244 | 白光灯 2000 245 | 四位排插 2000 246 | 氛围灯 2000 247 | 次卫 2000 248 | 衣帽间 2000 249 | LED筒灯 2000 250 | 所有 2000 251 | 吸顶灯 2000 252 | 摄像头 2000 253 | 空气炸锅 2000 254 | LED夜灯 2000 255 | LED彩光灯带 2000 256 | 电陶炉 2000 257 | 电热毯 2000 258 | 机顶盒 2000 259 | 智能灯泡 2000 260 | -------------------------------------------------------------------------------- /joint_model_knowl_v6_with_domain_knowledge/a1_generate_knowledges.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #1.read a line 3 | #2.get 1)user_speech, 2)intent, 3)slots, 4)get knowledges for the slots 4 | import json 5 | import codecs 6 | import os 7 | import random 8 | slot_values_file='slot_values.txt' 9 | slot_value_name_pair_file='slot_pairs.txt' 10 | slot_names_file='slot_names.txt' 11 | splitter='|&|' 12 | splitter_slot_names='||' 13 | 14 | def get_knowledge(data_source_file,knowledge_path,test_mode=False): 15 | #if target file not exist, create; otherwise return 16 | slot_value_name_pair_filee=knowledge_path+"/"+slot_value_name_pair_file 17 | slot_values_filee=knowledge_path + "/" + slot_values_file 18 | slot_names_filee=knowledge_path + "/" + slot_names_file 19 | if os.path.exists(slot_value_name_pair_filee) and os.path.exists(slot_values_filee) and os.path.exists(slot_names_filee): 20 | print("knowledge exists. will not generate it.") 21 | return 22 | else: 23 | print("knowledge not exists. will start to generate it.") 24 | 25 | file_object=codecs.open(data_source_file,'r','utf8') 26 | lines=file_object.readlines() 27 | random.shuffle(lines) 28 | if test_mode: 29 | lines=lines[0:20000] 30 | print("get_knowledge.length of lines:",len(lines)) 31 | knowledge_dict = {} 32 | slot_name_set=set() 33 | for i,line in enumerate(lines): 34 | if len(line.strip())<2: 35 | continue 36 | try: 37 | myjson = json.loads(line) 38 | except: 39 | continue 40 | elements = myjson['actions'] 41 | for i, element in enumerate(elements): 42 | target = element['target'] 43 | actor = element['actor'] 44 | slots = element['slots'] 45 | if actor == 'a' and target == 's': 46 | for i, element in enumerate(slots): 47 | slot_name = element['name'] 48 | slot_value = element['value'] 49 | slot_name_set.add(slot_name) 50 | sett = knowledge_dict.get(slot_value, None) 51 | if sett is None: # slot_value is not exists===>create a list. 52 | sett = set() 53 | sett.add(slot_name) 54 | knowledge_dict[slot_value] = sett 55 | else: # slot_value is exists===>append to exist list. 56 | sett.add(slot_name) 57 | knowledge_dict[slot_value] = sett 58 | 59 | #print 60 | #1.write slot_value to file system 61 | #2.write slot_value-slot_name pair to file system 62 | #3.write total slot name to file systm 63 | #ii = 0 64 | slot_values_file_object = codecs.open(slot_values_filee, 'w', 'utf-8') 65 | slot_value_name_pair_file_object=codecs.open(slot_value_name_pair_filee,'w','utf-8') 66 | slot_names_file_object=codecs.open(slot_names_filee,'w','utf-8') 67 | 68 | #if not os.path.exists(slot_value_name_pair_file) and not os.path.exists(slot_values_file) : 69 | for k, v in knowledge_dict.items(): 70 | if len(k)<6: #only save short context 71 | slot_value_name_pair_file_object.write(k+splitter+splitter_slot_names.join(list(v))+"\n") 72 | seg_value=str(100000) if len(k)==1 else str(2000) 73 | slot_values_file_object.write(k+" "+seg_value+"\n") 74 | #ii = ii + 1 75 | 76 | slot_values_file_object.close() 77 | slot_value_name_pair_file_object.close() 78 | 79 | print("slot_name_set:",slot_name_set) 80 | #if not os.path.exists(slot_names_file): 81 | for element in slot_name_set: 82 | slot_names_file_object.write(element+"\n") 83 | slot_names_file_object.close() 84 | 85 | return #knowledge_dict 86 | 87 | #print("knowledge_dict:",knowledge_dict) 88 | 89 | data_source='knowledge/sht_20171125.txt' 90 | knowledge_path='skill3' 91 | #get_knowledge(data_source,knowledge_path) 92 | -------------------------------------------------------------------------------- /joint_model_knowl_v8_slot_condition_intent/a1_generate_knowledges.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #1.read a line 3 | #2.get 1)user_speech, 2)intent, 3)slots, 4)get knowledges for the slots 4 | import json 5 | import codecs 6 | import os 7 | import random 8 | slot_values_file='slot_values.txt' 9 | slot_value_name_pair_file='slot_pairs.txt' 10 | slot_names_file='slot_names.txt' 11 | splitter='|&|' 12 | splitter_slot_names='||' 13 | 14 | def get_knowledge(data_source_file,knowledge_path,test_mode=False): 15 | #if target file not exist, create; otherwise return 16 | slot_value_name_pair_filee=knowledge_path+"/"+slot_value_name_pair_file 17 | slot_values_filee=knowledge_path + "/" + slot_values_file 18 | slot_names_filee=knowledge_path + "/" + slot_names_file 19 | if os.path.exists(slot_value_name_pair_filee) and os.path.exists(slot_values_filee) and os.path.exists(slot_names_filee): 20 | print("knowledge exists. will not generate it.") 21 | return 22 | else: 23 | print("knowledge not exists. will start to generate it.") 24 | 25 | file_object=codecs.open(data_source_file,'r','utf8') 26 | lines=file_object.readlines() 27 | random.shuffle(lines) 28 | if test_mode: 29 | lines=lines[0:20000] 30 | print("get_knowledge.length of lines:",len(lines)) 31 | knowledge_dict = {} 32 | slot_name_set=set() 33 | for i,line in enumerate(lines): 34 | if len(line.strip())<2: 35 | continue 36 | try: 37 | myjson = json.loads(line) 38 | except: 39 | continue 40 | elements = myjson['actions'] 41 | for i, element in enumerate(elements): 42 | target = element['target'] 43 | actor = element['actor'] 44 | slots = element['slots'] 45 | if actor == 'a' and target == 's': 46 | for i, element in enumerate(slots): 47 | slot_name = element['name'] 48 | slot_value = element['value'] 49 | slot_name_set.add(slot_name) 50 | sett = knowledge_dict.get(slot_value, None) 51 | if sett is None: # slot_value is not exists===>create a list. 52 | sett = set() 53 | sett.add(slot_name) 54 | knowledge_dict[slot_value] = sett 55 | else: # slot_value is exists===>append to exist list. 56 | sett.add(slot_name) 57 | knowledge_dict[slot_value] = sett 58 | 59 | #print 60 | #1.write slot_value to file system 61 | #2.write slot_value-slot_name pair to file system 62 | #3.write total slot name to file systm 63 | #ii = 0 64 | slot_values_file_object = codecs.open(slot_values_filee, 'w', 'utf-8') 65 | slot_value_name_pair_file_object=codecs.open(slot_value_name_pair_filee,'w','utf-8') 66 | slot_names_file_object=codecs.open(slot_names_filee,'w','utf-8') 67 | 68 | #if not os.path.exists(slot_value_name_pair_file) and not os.path.exists(slot_values_file) : 69 | for k, v in knowledge_dict.items(): 70 | if len(k)<=6: #only save short context 71 | slot_value_name_pair_file_object.write(k+splitter+splitter_slot_names.join(list(v))+"\n") 72 | seg_value=str(100000) if len(k)==1 else str(2000) 73 | slot_values_file_object.write(k+" "+seg_value+"\n") 74 | #ii = ii + 1 75 | 76 | slot_values_file_object.close() 77 | slot_value_name_pair_file_object.close() 78 | 79 | print("slot_name_set:",slot_name_set) 80 | #if not os.path.exists(slot_names_file): 81 | for element in slot_name_set: 82 | slot_names_file_object.write(element+"\n") 83 | slot_names_file_object.close() 84 | 85 | return #knowledge_dict 86 | 87 | #print("knowledge_dict:",knowledge_dict) 88 | 89 | data_source='knowledge/sht_20171125.txt' 90 | knowledge_path='skill3' 91 | #get_knowledge(data_source,knowledge_path) 92 | -------------------------------------------------------------------------------- /joint_model_knowl_v7_with_domain_knowledge_context_window/a1_generate_knowledges.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #1.read a line 3 | #2.get 1)user_speech, 2)intent, 3)slots, 4)get knowledges for the slots 4 | import json 5 | import codecs 6 | import os 7 | import random 8 | slot_values_file='slot_values.txt' 9 | slot_value_name_pair_file='slot_pairs.txt' 10 | slot_names_file='slot_names.txt' 11 | splitter='|&|' 12 | splitter_slot_names='||' 13 | 14 | def get_knowledge(data_source_file,knowledge_path,test_mode=False): 15 | #if target file not exist, create; otherwise return 16 | slot_value_name_pair_filee=knowledge_path+"/"+slot_value_name_pair_file 17 | slot_values_filee=knowledge_path + "/" + slot_values_file 18 | slot_names_filee=knowledge_path + "/" + slot_names_file 19 | if os.path.exists(slot_value_name_pair_filee) and os.path.exists(slot_values_filee) and os.path.exists(slot_names_filee): 20 | print("knowledge exists. will not generate it.") 21 | return 22 | else: 23 | print("knowledge not exists. will start to generate it.") 24 | 25 | file_object=codecs.open(data_source_file,'r','utf8') 26 | lines=file_object.readlines() 27 | random.shuffle(lines) 28 | if test_mode: 29 | lines=lines[0:20000] 30 | print("get_knowledge.length of lines:",len(lines)) 31 | knowledge_dict = {} 32 | slot_name_set=set() 33 | for i,line in enumerate(lines): 34 | if len(line.strip())<2: 35 | continue 36 | try: 37 | myjson = json.loads(line) 38 | except: 39 | continue 40 | elements = myjson['actions'] 41 | for i, element in enumerate(elements): 42 | target = element['target'] 43 | actor = element['actor'] 44 | slots = element['slots'] 45 | if actor == 'a' and target == 's': 46 | for i, element in enumerate(slots): 47 | slot_name = element['name'] 48 | slot_value = element['value'] 49 | slot_name_set.add(slot_name) 50 | sett = knowledge_dict.get(slot_value, None) 51 | if sett is None: # slot_value is not exists===>create a list. 52 | sett = set() 53 | sett.add(slot_name) 54 | knowledge_dict[slot_value] = sett 55 | else: # slot_value is exists===>append to exist list. 56 | sett.add(slot_name) 57 | knowledge_dict[slot_value] = sett 58 | 59 | #print 60 | #1.write slot_value to file system 61 | #2.write slot_value-slot_name pair to file system 62 | #3.write total slot name to file systm 63 | #ii = 0 64 | slot_values_file_object = codecs.open(slot_values_filee, 'w', 'utf-8') 65 | slot_value_name_pair_file_object=codecs.open(slot_value_name_pair_filee,'w','utf-8') 66 | slot_names_file_object=codecs.open(slot_names_filee,'w','utf-8') 67 | 68 | #if not os.path.exists(slot_value_name_pair_file) and not os.path.exists(slot_values_file) : 69 | for k, v in knowledge_dict.items(): 70 | if len(k)<6: #only save short context 71 | slot_value_name_pair_file_object.write(k+splitter+splitter_slot_names.join(list(v))+"\n") 72 | seg_value=str(100000) if len(k)==1 else str(2000) 73 | slot_values_file_object.write(k+" "+seg_value+"\n") 74 | #ii = ii + 1 75 | 76 | slot_values_file_object.close() 77 | slot_value_name_pair_file_object.close() 78 | 79 | print("slot_name_set:",slot_name_set) 80 | #if not os.path.exists(slot_names_file): 81 | for element in slot_name_set: 82 | slot_names_file_object.write(element+"\n") 83 | slot_names_file_object.close() 84 | 85 | return #knowledge_dict 86 | 87 | #print("knowledge_dict:",knowledge_dict) 88 | 89 | data_source='knowledge/sht_20171125.txt' 90 | knowledge_path='skill3' 91 | #get_knowledge(data_source,knowledge_path) 92 | -------------------------------------------------------------------------------- /joint_model_naive_v1/joint_intent_slots_navie_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_naive_model import joint_naive_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",15,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_integer("intent_num_classes",31,"number of classes for intent") 34 | tf.app.flags.DEFINE_integer("vocab_size",382,"vocabulary size for input(x)") 35 | tf.app.flags.DEFINE_integer("slots_num_classes",4,"number of classes for slots") 36 | 37 | #create session and load the model from checkpoint 38 | config = tf.ConfigProto() 39 | config.gpu_options.allow_growth = True 40 | sess = tf.Session(config=config) 41 | FLAGS.batch_size = 1 42 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 43 | model = joint_naive_model(FLAGS.intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 44 | FLAGS.sequence_length, FLAGS.vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 45 | sequence_length_batch, FLAGS.slots_num_classes, FLAGS.is_training) 46 | # initialize Saver 47 | saver = tf.train.Saver() 48 | print('restoring Variables from Checkpoint!') 49 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 50 | # load vocabulary for intent and slot name 51 | word2id = create_or_load_vocabulary(None) 52 | id2word = {value: key for key, value in word2id.items()} 53 | word2id_intent = create_or_load_vocabulary_intent(None) 54 | id2word_intent = {value: key for key, value in word2id_intent.items()} 55 | word2id_slotname = create_or_load_vocabulary_slotname_save(None) 56 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 57 | 58 | def main(_): 59 | sentence=u'开灯' #u'帮我打开厕所的灯' 60 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 61 | intent, slots=predict(sentence) 62 | print(sentence) 63 | print("intent:%s" %intent) 64 | for slot_name,slot_value in slots.items(): 65 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 66 | 67 | predict_interactive() 68 | 69 | def predict(sentence): 70 | """ 71 | :param sentence: a sentence. 72 | :return: intent and slots 73 | """ 74 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length) 75 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length))} 76 | logits_intent,logits_slots = sess.run([model.logits_intent,model.logits_slots], feed_dict) 77 | intent,slots=get_result(logits_intent,logits_slots,sentence_indices) 78 | return intent,slots 79 | 80 | def predict_interactive(): 81 | sys.stdout.write("Please Input Story.>") 82 | sys.stdout.flush() 83 | question = sys.stdin.readline() 84 | while question: 85 | #1.predict using quesiton 86 | intent, slots=predict(question) 87 | #2.print 88 | print("intent:%s" % intent) 89 | for slot_name, slot_value in slots.items(): 90 | print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 91 | #3.read new input 92 | print("Please Input Story>") 93 | sys.stdout.flush() 94 | question = sys.stdin.readline() 95 | 96 | 97 | 98 | def get_result(logits_intent,logits_slots,sentence_indices): 99 | index_intent= np.argmax(logits_intent[0]) #index of intent 100 | intent=id2word_intent[index_intent] 101 | 102 | slots=[] 103 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 104 | for i,index in enumerate(indices_slots): 105 | slots.append(id2word_slotname[index]) 106 | slots_dict={} 107 | for i,slot in enumerate(slots): 108 | word=id2word[sentence_indices[i]] 109 | #print(i,"slot:",slot,";word:",word,";slots!=O:",slots!=O) 110 | if slot!=O and word!=PAD and word!=UNK: 111 | slots_dict[slot]=word 112 | return intent,slots_dict 113 | 114 | if __name__ == "__main__": 115 | tf.app.run() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Joint model for intent detection and slot filling based on attention, input alignment and knowledge. 2 | 3 | with ability to detect whether a input sentence is a noise input or meanfuling input by combine feature from domain detection, intent detection and slot filling. 4 | 5 | with ability to assign possibility to a input sentence by using language model. 6 | 7 | Introduction: 8 | ------------------------------------------------------------------------------------- 9 | 1.intent detection and slot filling joint model which share encoding information 10 | 11 | 2.incorporate knowledge information with embedding for both intent detection and slot filling. this embedding share the same embedding space with slots output. 12 | 13 | 3.use bi-direction RNN and CNN to do intent detection 14 | 15 | 4.use slots middle output as a feature for intent detection to boost performance 16 | 17 | 5.domain detection is availabile by using CNN, same structure as intent detection. domain is a high level concept which indicates 18 | area that intent(s) belongs to. 19 | 20 | 6.similiarity module is used to detect most similiar training data for any user input 21 | 22 | 7.toy task: input a sequence of natural number, such as [5,7,2,6,8,3]. 23 | for slot filling: count label each number to 0 or 1. if sum of a number together with its previous and next number is great than a threshold(such as 14), we mark it as 1. otherwise 0. 24 | in this case, output of slot filling will be:[0,0,1,1,1,0] 25 | for intent detection, count how many number totally is marked as 1. in this case, output of intent will be:3. 26 | 27 | Performance: 28 | ------------------------------------------------------------------------------------- 29 | 30 | dataset1: 31 | |---slot_naive(V6)|---slot_alime(V7)----------| 32 | 33 | |------97.9%------|----99.8%%-----------------| 34 | 35 | dataset2: 36 | 37 | |---intent_tmall|---intent_tmall(similiarity)|---intent_alime|---intent_alime(similiarity)|---TextCNN---|---TextCNN(similiarity)| 38 | 39 | |------95.37%|------72.0%-----------------|----93.0%------|----62.9%-----------------|----95.70%-------|----73.5%-------------| 40 | 41 | 42 | 43 | Usage: 44 | ------------------------------------------------------------------------------------- 45 | 1.train the model: train() of xxx_train.py 46 | 47 | 2.test the model: predict() of xxx_predict.py 48 | 49 | 3. for model structure, you can check xxx_model.py 50 | 51 | Description for different versions: 52 | ------------------------------------------------------------------------------------- 53 | V0 (seq2seq version): use TextCNN for intent, use encoder-decoder(seq2seq) model for slots. train() and predict() for toy task is available under a1_joint_intent_slots_model.py 54 | 55 | ----------------------------- 56 | V1 (naive version): 57 | 58 | use bi-directional GRU to encode input. this is share between intent detection and slots filling. 59 | 60 | intent was predicted directically after fully connected layer based on sum up for different time step. 61 | 62 | slots were predicted directically after fully connected layer for each time step. 63 | 64 | ----------------------------- 65 | V2 (simple version): 66 | add knowledge to naive version. knowledge is embedding, and used as additional feature to make prediction both for intent and slots. 67 | 68 | ----------------------------- 69 | 70 | V3 (p-BOW,TextCNN,similiarity module): 71 | 72 | use positional bag of words to encoder input sentence. this is share between intent detection and slots filling. 73 | 74 | TextCNN is used for intent detection. knowlege is embedded, transformed and used as feature together with output of TextCNN to make 75 | 76 | a prediction. 77 | 78 | similiarity module is used to detect the most similiar question for input sentence. it used the representation learned by positional 79 | 80 | bag of words. this module is useful when you want to check similiar question or when you want to know the coverage of your dataset; 81 | 82 | you can get a prediction by simply use the intent(or called answer) for the most similiar question of the input sentence. 83 | 84 | ----------------------------- 85 | 86 | V4(Ali me style TextCNN): 87 | word embedding is concated with knowledge embedding to get better representation for each word. 'Hopefully' to capture additional 88 | 89 | infomration that is relevant to make prediction. 90 | 91 | other part is same as V3 92 | 93 | ----------------------------- 94 | 95 | V5(TextCNN): 96 | 97 | just to make a comparision with V4 by not using any knowledge. 98 | 99 | ----------------------------- 100 | 101 | V6(+domain version) 102 | 103 | domain detection is predicted besides intent detection and slot filling. 104 | 105 | ----------------------------- 106 | 107 | V7(+context window for slot filling) 108 | 109 | mainly change slot filling part: 1.word vector+symbol vector 2.context window 3.nolinear projection 4.bi-directional lstm 110 | 111 | for intent and domain detection, use representation from concat of word vector and symbol vector. 112 | 113 | ----------------------------- 114 | V8(intent condition on domain; slot filling condition on intent) 115 | 116 | given a domain, intent is limit to a subset of total intents; given a intent, slot name is limited to a subset of total slot names. this model doing this 117 | 118 | by providing hidden states of domain together with other features before doing intent detection; it works similiar for slot filling. 119 | 120 | ----------------------------- 121 | 122 | ![alt text](https://github.com/brightmart/slot_filling_intent_joint_model/blob/master/resources/JOINT_MODEL.JPG) 123 | 124 | ![alt text](https://github.com/brightmart/slot_filling_intent_joint_model/blob/master/resources/TextCNN.JPG) 125 | 126 | ![alt text](https://github.com/brightmart/slot_filling_intent_joint_model/blob/master/resources/slot_filling_alime.JPG) 127 | 128 | Conclude: 129 | ------------------------------------------------------------------------------------- 130 | Different models can be used for intent detection and slots filling. Some model's performance is strong than others in some dataset, while other model's peformance is better in other dataset. So we need to do experiment using different model to get a better performance. 131 | 132 | Reference: 133 | ------------------------------------------------------------------------------------- 134 | 1.Attention-Based Recurrent Neural Network Models for Joint Intent Detection and Slot Filling, 135 | 136 | https://arxiv.org/pdf/1609.01454.pdf 137 | 138 | 2.阿里AI Labs王刚解读9小时卖出百万台的“天猫精灵” | 高山大学(GASA), 139 | 140 | http://www.sohu.com/a/206109679_473283 141 | 142 | 3.史上最全!阿里智能人机交互的核心技术解析 143 | https://yq.aliyun.com/articles/277907?spm=5176.100244.teamhomeleft.54.SKEyCU 144 | -------------------------------------------------------------------------------- /joint_model_knowl_v0/a1_joint_intent_slots_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | import tensorflow as tf 7 | import numpy as np 8 | import os 9 | import codecs 10 | from a1_seq2seq_attention_model import seq2seq_attention_model 11 | from data_util import load_test_data,load_vocab_as_dict,_GO,_PAD,_EOS,_UNK 12 | from tflearn.data_utils import pad_sequences 13 | from a1_preprocess import preprocess_english_file 14 | 15 | #configuration 16 | FLAGS=tf.app.flags.FLAGS 17 | tf.app.flags.DEFINE_float("learning_rate",0.01,"learning rate") 18 | tf.app.flags.DEFINE_integer("batch_size", 400, "Batch size for training/evaluating.") #400 批处理的大小 32-->128 19 | tf.app.flags.DEFINE_integer("decay_steps", 6000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 20 | tf.app.flags.DEFINE_float("decay_rate", 1.0, "Rate of decay for learning rate.") #0.87一次衰减多少 21 | tf.app.flags.DEFINE_string("ckpt_dir","ckpt_ai_challenger_translation/","checkpoint location for the model") 22 | tf.app.flags.DEFINE_integer("sequence_length",30,"max sentence length") 23 | tf.app.flags.DEFINE_integer("decoder_sent_length",30,"length of decoder inputs") 24 | tf.app.flags.DEFINE_integer("embed_size",256,"embedding size") 25 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 26 | tf.app.flags.DEFINE_boolean("use_embedding",True,"whether to use embedding or not.") 27 | tf.app.flags.DEFINE_integer("hidden_size",256,"hidden size") 28 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 29 | tf.app.flags.DEFINE_string("predict_target_file","ckpt_ai_challenger_translation/s2q_attention.csv","target file path for final prediction") 30 | tf.app.flags.DEFINE_string("data_en_test_path",'./data/test_a_20170923.sgm',"target file path for final prediction") 31 | tf.app.flags.DEFINE_string("data_en_test_processed_path",'./data/test_a_20170923.sgm.processed',"target file path for final prediction") 32 | tf.app.flags.DEFINE_string("vocabulary_cn_path","./data/vocabulary.zh","path of traning data.") 33 | tf.app.flags.DEFINE_string("vocabulary_en_path","./data/vocabulary.en","path of traning data.") 34 | tf.app.flags.DEFINE_boolean("use_beam_search",True,"whether use beam search during decoding.") 35 | 36 | def main(_): 37 | #1.load test data 38 | vocab_cn, vocab_en = load_vocab_as_dict(FLAGS.vocabulary_cn_path, FLAGS.vocabulary_en_path) 39 | flag_data_en_test_processed_path=os.path.exists(FLAGS.data_en_test_processed_path) 40 | print("processed of english source file exists or not:",flag_data_en_test_processed_path) 41 | if not flag_data_en_test_processed_path: 42 | preprocess_english_file(FLAGS.data_en_test_path, FLAGS.data_en_test_processed_path) 43 | test=load_test_data(FLAGS.data_en_test_processed_path, vocab_en, FLAGS.decoder_sent_length) 44 | print("test[0:10]:",test[0:10]) 45 | test = pad_sequences(test, maxlen=FLAGS.sequence_length, value=0.) # padding to max length 46 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 47 | 48 | #2.create session,model,feed data to make a prediction 49 | config=tf.ConfigProto() 50 | config.gpu_options.allow_growth=True 51 | with tf.Session(config=config) as sess: 52 | model = seq2seq_attention_model(len(vocab_cn), FLAGS.learning_rate, FLAGS.batch_size, FLAGS.decay_steps, 53 | FLAGS.decay_rate, FLAGS.sequence_length, len(vocab_en), FLAGS.embed_size, 54 | FLAGS.hidden_size, sequence_length_batch,FLAGS.is_training,decoder_sent_length=FLAGS.decoder_sent_length, 55 | l2_lambda=FLAGS.l2_lambda,use_beam_search=FLAGS.use_beam_search) 56 | saver=tf.train.Saver() 57 | if os.path.exists(FLAGS.ckpt_dir+"checkpoint"): 58 | print("Restoring Variables from Checkpoint") 59 | saver.restore(sess,tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 60 | else: 61 | print("Can't find the checkpoint.going to stop") 62 | return 63 | #feed data, to get logits 64 | number_of_test_data = len(test) 65 | print("number_of_test_data:", number_of_test_data) 66 | index = 0 67 | predict_target_file_f = codecs.open(FLAGS.predict_target_file, 'a', 'utf8') 68 | decoder_input=np.array([[vocab_cn[_GO]] + [vocab_cn[_PAD]] * (FLAGS.decoder_sent_length - 1)]*FLAGS.batch_size) 69 | print("decoder_input:", decoder_input.shape) 70 | decoder_input = np.reshape(decoder_input, [-1, FLAGS.decoder_sent_length]) 71 | print("decoder_input:",decoder_input.shape) 72 | vocab_cn_index2word = dict([val, key] for key, val in vocab_cn.items()) 73 | 74 | for start, end in zip(range(0, number_of_test_data, FLAGS.batch_size),range(FLAGS.batch_size, number_of_test_data + 1, FLAGS.batch_size)): 75 | predictions = sess.run(model.predictions, # predictions:[batch_size,decoder_sent_length] 76 | feed_dict={model.input_x: test[start:end], 77 | model.decoder_input: decoder_input, 78 | model.dropout_keep_prob: 1}) # 'shape of logits:', ( 1, 1999) 79 | # 6. get lable using logtis 80 | output_sentence_list= get_label_using_logits(predictions, vocab_cn_index2word, vocab_cn) 81 | # 7. write question id and labels to file system. 82 | for sentence in output_sentence_list: 83 | predict_target_file_f.write(sentence+"\n") 84 | predict_target_file_f.close() 85 | 86 | def get_label_using_logits(predictions, vocab_cn_index2word, vocab_cn): 87 | """ 88 | :param predictions: array as [batch_size,decoder_sent_length] 89 | :param vocab_cn_index2word: 90 | :param vocab_cn: 91 | :return: 92 | """ 93 | #print("predictions:",predictions.shape) 94 | eos_index=vocab_cn[_EOS] 95 | result_list=[] 96 | for ii,selected_token_ids in enumerate(predictions): 97 | #print("selected_token_ids0:",selected_token_ids.shape) 98 | selected_token_ids=list(selected_token_ids) 99 | #print("selected_token_ids1:",selected_token_ids) 100 | if eos_index in selected_token_ids: 101 | eos_index = selected_token_ids.index(eos_index) 102 | selected_token_ids=selected_token_ids[0:eos_index] 103 | output_sentence = "".join([vocab_cn_index2word[index] for index in selected_token_ids]) 104 | if _PAD in output_sentence: 105 | output_sentence=output_sentence[0:output_sentence.find(_PAD)] 106 | result_list.append(output_sentence) 107 | return result_list 108 | if __name__ == "__main__": 109 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_naive_v1/joint_intent_slots_naive_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_naive_model import joint_naive_model 11 | from a1_data_util import generate_training_data 12 | import math 13 | import pickle 14 | 15 | #configuration 16 | FLAGS=tf.app.flags.FLAGS 17 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 18 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 19 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 20 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 21 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint/","checkpoint location for the model") 22 | tf.app.flags.DEFINE_integer("sequence_length",15,"max sentence length") #100 23 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 24 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 25 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 26 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 27 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 28 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 29 | 30 | tf.app.flags.DEFINE_integer("intent_num_classes",31,"number of classes for intent") 31 | tf.app.flags.DEFINE_integer("vocab_size",382,"vocabulary size for input(x)") 32 | tf.app.flags.DEFINE_integer("slots_num_classes",4,"number of classes for slots") 33 | tf.app.flags.DEFINE_string("data_source","knowledge/sht_20171125.txt","file for data source") 34 | 35 | 36 | def main(_): 37 | #1. load data 38 | traing_data, valid_data, test_data = generate_training_data(FLAGS.data_source) 39 | print("training_data:",type(traing_data),"") 40 | x_train, y_intent_train, y_slots_train=traing_data 41 | x_valid, y_intent_valid, y_slots_valid = valid_data 42 | x_test, y_intent_test, y_slots_test = test_data 43 | 44 | # 2.create session. 45 | config = tf.ConfigProto() 46 | config.gpu_options.allow_growth = True 47 | with tf.Session(config=config) as sess: 48 | # Instantiate Model 49 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 50 | model=joint_naive_model(FLAGS.intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 51 | FLAGS.vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,FLAGS.slots_num_classes,FLAGS.is_training) 52 | # Initialize Save 53 | saver = tf.train.Saver() 54 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 55 | print("Restoring Variables from Checkpoint") 56 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 57 | else: 58 | print('Initializing Variables') 59 | sess.run(tf.global_variables_initializer()) 60 | curr_epoch = sess.run(model.epoch_step) 61 | # 3.feed data & training 62 | number_of_training_data = len(x_train) 63 | print("number_of_training_data:", number_of_training_data) 64 | previous_eval_loss = 10000 65 | best_eval_loss = 10000 66 | batch_size = FLAGS.batch_size 67 | for epoch in range(curr_epoch, FLAGS.num_epochs): 68 | loss, acc_intent,acc_slot, counter = 0.0,0.0, 0.0, 0 69 | for start, end in zip(range(0, number_of_training_data, batch_size), 70 | range(batch_size, number_of_training_data, batch_size)): 71 | if epoch == 0 and counter == 0:#print sample to have a look 72 | print("trainX[start:end]:", x_train[start:end]) 73 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 74 | feed_dict[model.y_intent] = y_intent_train[start:end] 75 | feed_dict[model.y_slots] = y_slots_train[start:end] 76 | curr_loss, curr_acc_intent,curr_acc_slot, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot, model.train_op],feed_dict) 77 | loss, counter, acc_intent,acc_slot = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot 78 | if counter % 50 == 0: 79 | print("joint_intent_slots_navie==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f" %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter))) 80 | 81 | if start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 82 | eval_loss,acc_intent,acc_slot = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size) 83 | print("joint_intent_slots_navie.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:",acc_intent,";acc_slot:",acc_slot) 84 | if eval_loss > previous_eval_loss: # if loss is not decreasing 85 | # reduce the learning rate by a factor of 0.5 86 | print("joint_intent_slots_navie==>validation.part.going to reduce the learning rate.") 87 | learning_rate1 = sess.run(model.learning_rate) 88 | lrr = sess.run([model.learning_rate_decay_half_op]) 89 | learning_rate2 = sess.run(model.learning_rate) 90 | print("joint_intent_slots_navie==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 91 | else: # loss is decreasing 92 | if eval_loss < best_eval_loss: 93 | print("joint_intent_slots_navie==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 94 | # save model to checkpoint 95 | save_path = FLAGS.ckpt_dir + "model.ckpt" 96 | saver.save(sess, save_path, global_step=epoch) 97 | best_eval_loss = eval_loss 98 | previous_eval_loss = eval_loss 99 | 100 | # epoch increment 101 | print("going to increment epoch counter....") 102 | sess.run(model.epoch_increment) 103 | 104 | # 5.最后在测试集上做测试,并报告测试准确率 Test 105 | test_loss, test_acc_intent,test_acc_slot = do_eval(sess, model, x_test, y_intent_test, y_slots_test, batch_size) 106 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot) 107 | pass 108 | 109 | # 在验证集上做验证,报告损失、精确度 110 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size): 111 | number_examples = len(x_valid) 112 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = 0.0,0.0, 0.0, 0 113 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 114 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 115 | feed_dict[model.y_intent] = y_intent_valid[start:end] 116 | feed_dict[model.y_slots] = y_slots_valid[start:end] 117 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot],feed_dict) 118 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , eval_acc_slot+curr_eval_acc_slot,eval_counter + 1 119 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter) 120 | 121 | 122 | if __name__ == "__main__": 123 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v2_simpl_modl_feat/joint_intent_slots_knowledge_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_model import joint_knowledge_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 35 | 36 | 37 | #create session and load the model from checkpoint 38 | # load vocabulary for intent and slot name 39 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 40 | id2word = {value: key for key, value in word2id.items()} 41 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 42 | id2word_intent = {value: key for key, value in word2id_intent.items()} 43 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 44 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 45 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 46 | 47 | intent_num_classes=len(word2id_intent) 48 | vocab_size=len(word2id) 49 | slots_num_classes=len(id2word_slotname) 50 | 51 | config = tf.ConfigProto() 52 | config.gpu_options.allow_growth = True 53 | sess = tf.Session(config=config) 54 | FLAGS.batch_size = 1 55 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 56 | model = joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 57 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 58 | sequence_length_batch, slots_num_classes, FLAGS.is_training) 59 | # initialize Saver 60 | saver = tf.train.Saver() 61 | print('restoring Variables from Checkpoint!') 62 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 63 | 64 | 65 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 66 | jieba.load_userdict(slot_values_file) 67 | 68 | def main(_): 69 | sentence=u'开灯' #u'帮我打开厕所的灯' 70 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 71 | intent,intent_logits, slots,slot_list=predict(sentence) 72 | print(sentence) 73 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 74 | #for slot_name,slot_value in slots.items(): 75 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 76 | for i,element in enumerate(slot_list): 77 | slot_name,slot_value=element 78 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 79 | 80 | predict_interactive() 81 | 82 | def predict(sentence,enable_knowledge=1): 83 | """ 84 | :param sentence: a sentence. 85 | :return: intent and slots 86 | """ 87 | print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 88 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 89 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 90 | print("predict.y_slots:",y_slots) 91 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)),model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length))} 92 | logits_intent,logits_slots = sess.run([model.logits_intent,model.logits_slots], feed_dict) 93 | intent,intent_logits,slots,slot_list=get_result(logits_intent,logits_slots,sentence_indices) 94 | return intent,intent_logits,slots,slot_list 95 | 96 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 97 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 98 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 99 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 100 | result=[word2id_slotname[O]]*sequence_length 101 | if enable_knowledge=='1' or enable_knowledge==1: 102 | for i,word in enumerate(user_speech_tokenized): 103 | slot_name=knowledge_dict.get(word,None) 104 | if slot_name is not None: 105 | result[i]=word2id_slotname[slot_name] 106 | return result 107 | 108 | def predict_interactive(): 109 | sys.stdout.write("Please Input Story.>") 110 | sys.stdout.flush() 111 | question = sys.stdin.readline() 112 | enable_knowledge=1 113 | while question: 114 | if question.find("disable_knowledge")>=0: 115 | enable_knowledge=0 116 | print("knowledge disabled") 117 | print("Please Input Story>") 118 | sys.stdout.flush() 119 | question = sys.stdin.readline() 120 | elif question.find("enable_knowledge")>=0: 121 | enable_knowledge=1 122 | #3.read new input 123 | print("knowledge enabled") 124 | print("Please Input Story>") 125 | sys.stdout.flush() 126 | question = sys.stdin.readline() 127 | 128 | #1.predict using quesiton 129 | intent, intent_logits,slots,slot_list=predict(question,enable_knowledge=enable_knowledge) 130 | #2.print 131 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 132 | #for slot_name, slot_value in slots.items(): 133 | # print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 134 | for i, element in enumerate(slot_list): 135 | slot_name, slot_value = element 136 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 137 | #3.read new input 138 | print("Please Input Story>") 139 | sys.stdout.flush() 140 | question = sys.stdin.readline() 141 | 142 | 143 | def get_result(logits_intent,logits_slots,sentence_indices): 144 | index_intent= np.argmax(logits_intent[0]) #index of intent 145 | intent_logits=logits_intent[0][index_intent] 146 | print("intent_logits:",index_intent) 147 | intent=id2word_intent[index_intent] 148 | 149 | slots=[] 150 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 151 | for i,index in enumerate(indices_slots): 152 | slots.append(id2word_slotname[index]) 153 | slots_dict={} 154 | slot_list=[] 155 | for i,slot in enumerate(slots): 156 | word=id2word[sentence_indices[i]] 157 | print(i,"slot:",slot,";word:",word) 158 | if slot!=O and word!=PAD and word!=UNK: 159 | slots_dict[slot]=word 160 | slot_list.append((slot,word)) 161 | return intent,intent_logits,slots_dict,slot_list 162 | 163 | if __name__ == "__main__": 164 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v5_without_knowledge/joint_intent_slots_knowledge_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_model import joint_knowledge_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid = valid_data 39 | x_test, y_intent_test, y_slots_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, counter = 0.0,0.0, 0.0, 0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 72 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 73 | feed_dict[model.y_intent] = y_intent_train[start:end] 74 | feed_dict[model.y_slots] = y_slots_train[start:end] 75 | curr_loss, curr_acc_intent,curr_acc_slot, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot, model.train_op],feed_dict) 76 | loss, counter, acc_intent,acc_slot = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot 77 | if counter % 50 == 0: 78 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f" %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter))) 79 | 80 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 81 | eval_loss,eval_acc_intent,eval_acc_slot = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size) 82 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:",eval_acc_intent,";acc_slot:",eval_acc_slot) 83 | if eval_loss > previous_eval_loss: # if loss is not decreasing 84 | # reduce the learning rate by a factor of 0.5 85 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 86 | learning_rate1 = sess.run(model.learning_rate) 87 | lrr = sess.run([model.learning_rate_decay_half_op]) 88 | learning_rate2 = sess.run(model.learning_rate) 89 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 90 | else: # loss is decreasing 91 | if eval_loss < best_eval_loss: 92 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 93 | # save model to checkpoint 94 | save_path = FLAGS.ckpt_dir + "model.ckpt" 95 | saver.save(sess, save_path, global_step=epoch) 96 | best_eval_loss = eval_loss 97 | previous_eval_loss = eval_loss 98 | 99 | # epoch increment 100 | print("going to increment epoch counter....") 101 | sess.run(model.epoch_increment) 102 | 103 | # 5.最后在测试集上做测试,并报告测试准确率 Test 104 | test_loss, test_acc_intent,test_acc_slot = do_eval(sess, model, x_test, y_intent_test, y_slots_test, batch_size) 105 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot) 106 | pass 107 | 108 | # 在验证集上做验证,报告损失、精确度 109 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size): 110 | number_examples = len(x_valid) 111 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = 0.0,0.0, 0.0, 0 112 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 113 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 114 | feed_dict[model.y_intent] = y_intent_valid[start:end] 115 | feed_dict[model.y_slots] = y_slots_valid[start:end] 116 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot],feed_dict) 117 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , eval_acc_slot+curr_eval_acc_slot,eval_counter + 1 118 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter) 119 | 120 | if __name__ == "__main__": 121 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v2_simpl_modl_feat/joint_intent_slots_knowledge_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_model import joint_knowledge_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | 35 | def main(_): 36 | #1. load data 37 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 38 | x_train, y_intent_train, y_slots_train=traing_data 39 | x_valid, y_intent_valid, y_slots_valid = valid_data 40 | x_test, y_intent_test, y_slots_test = test_data 41 | 42 | # 2.create session. 43 | config = tf.ConfigProto() 44 | config.gpu_options.allow_growth = True 45 | with tf.Session(config=config) as sess: 46 | # Instantiate Model 47 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 48 | model=joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 49 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training) 50 | # Initialize Save 51 | saver = tf.train.Saver() 52 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 53 | print("Restoring Variables from Checkpoint") 54 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 55 | else: 56 | print('Initializing Variables') 57 | sess.run(tf.global_variables_initializer()) 58 | curr_epoch = sess.run(model.epoch_step) 59 | # 3.feed data & training 60 | number_of_training_data = len(x_train) 61 | print("number_of_training_data:", number_of_training_data) 62 | previous_eval_loss = 10000 63 | best_eval_loss = 10000 64 | batch_size = FLAGS.batch_size 65 | for epoch in range(curr_epoch, FLAGS.num_epochs): 66 | loss, acc_intent,acc_slot, counter = 0.0,0.0, 0.0, 0 67 | for start, end in zip(range(0, number_of_training_data, batch_size), 68 | range(batch_size, number_of_training_data, batch_size)): 69 | if epoch == 0 and counter == 0:#print sample to have a look 70 | print("trainX[start:end]:", x_train[0:3]) 71 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 72 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 73 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 74 | feed_dict[model.y_intent] = y_intent_train[start:end] 75 | feed_dict[model.y_slots] = y_slots_train[start:end] 76 | curr_loss, curr_acc_intent,curr_acc_slot, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot, model.train_op],feed_dict) 77 | loss, counter, acc_intent,acc_slot = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot 78 | if counter % 50 == 0: 79 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f" %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter))) 80 | 81 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 82 | eval_loss,eval_acc_intent,eval_acc_slot = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size) 83 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:",eval_acc_intent,";acc_slot:",eval_acc_slot) 84 | if eval_loss > previous_eval_loss: # if loss is not decreasing 85 | # reduce the learning rate by a factor of 0.5 86 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 87 | learning_rate1 = sess.run(model.learning_rate) 88 | lrr = sess.run([model.learning_rate_decay_half_op]) 89 | learning_rate2 = sess.run(model.learning_rate) 90 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 91 | else: # loss is decreasing 92 | if eval_loss < best_eval_loss: 93 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 94 | # save model to checkpoint 95 | save_path = FLAGS.ckpt_dir + "model.ckpt" 96 | saver.save(sess, save_path, global_step=epoch) 97 | best_eval_loss = eval_loss 98 | previous_eval_loss = eval_loss 99 | 100 | # epoch increment 101 | print("going to increment epoch counter....") 102 | sess.run(model.epoch_increment) 103 | 104 | # 5.最后在测试集上做测试,并报告测试准确率 Test 105 | test_loss, test_acc_intent,test_acc_slot = do_eval(sess, model, x_test, y_intent_test, y_slots_test, batch_size) 106 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot) 107 | pass 108 | 109 | # 在验证集上做验证,报告损失、精确度 110 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size): 111 | number_examples = len(x_valid) 112 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = 0.0,0.0, 0.0, 0 113 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 114 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 115 | feed_dict[model.y_intent] = y_intent_valid[start:end] 116 | feed_dict[model.y_slots] = y_slots_valid[start:end] 117 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot],feed_dict) 118 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , eval_acc_slot+curr_eval_acc_slot,eval_counter + 1 119 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter) 120 | 121 | if __name__ == "__main__": 122 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v3_bi_directional_cnn_tmall/joint_intent_slots_knowledge_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_model import joint_knowledge_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid = valid_data 39 | x_test, y_intent_test, y_slots_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, counter = 0.0,0.0, 0.0, 0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 72 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 73 | feed_dict[model.y_intent] = y_intent_train[start:end] 74 | feed_dict[model.y_slots] = y_slots_train[start:end] 75 | curr_loss, curr_acc_intent,curr_acc_slot, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot, model.train_op],feed_dict) 76 | loss, counter, acc_intent,acc_slot = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot 77 | if counter % 50 == 0: 78 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f" %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter))) 79 | 80 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 81 | eval_loss,eval_acc_intent,eval_acc_slot = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size) 82 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:",eval_acc_intent,";acc_slot:",eval_acc_slot) 83 | if eval_loss > previous_eval_loss: # if loss is not decreasing 84 | # reduce the learning rate by a factor of 0.5 85 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 86 | learning_rate1 = sess.run(model.learning_rate) 87 | lrr = sess.run([model.learning_rate_decay_half_op]) 88 | learning_rate2 = sess.run(model.learning_rate) 89 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 90 | else: # loss is decreasing 91 | if eval_loss < best_eval_loss: 92 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 93 | # save model to checkpoint 94 | save_path = FLAGS.ckpt_dir + "model.ckpt" 95 | saver.save(sess, save_path, global_step=epoch) 96 | best_eval_loss = eval_loss 97 | previous_eval_loss = eval_loss 98 | 99 | # epoch increment 100 | print("going to increment epoch counter....") 101 | sess.run(model.epoch_increment) 102 | 103 | # 5.最后在测试集上做测试,并报告测试准确率 Test 104 | test_loss, test_acc_intent,test_acc_slot = do_eval(sess, model, x_test, y_intent_test, y_slots_test, batch_size) 105 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot) 106 | pass 107 | 108 | # 在验证集上做验证,报告损失、精确度 109 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size): 110 | number_examples = len(x_valid) 111 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = 0.0,0.0, 0.0, 0 112 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 113 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 114 | feed_dict[model.y_intent] = y_intent_valid[start:end] 115 | feed_dict[model.y_slots] = y_slots_valid[start:end] 116 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot],feed_dict) 117 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , eval_acc_slot+curr_eval_acc_slot,eval_counter + 1 118 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter) 119 | 120 | if __name__ == "__main__": 121 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v4_cnn_with_symbol_alime/joint_intent_slots_knowledge_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_model import joint_knowledge_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid = valid_data 39 | x_test, y_intent_test, y_slots_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, counter = 0.0,0.0, 0.0, 0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 72 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 73 | feed_dict[model.y_intent] = y_intent_train[start:end] 74 | feed_dict[model.y_slots] = y_slots_train[start:end] 75 | curr_loss, curr_acc_intent,curr_acc_slot, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot, model.train_op],feed_dict) 76 | loss, counter, acc_intent,acc_slot = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot 77 | if counter % 50 == 0: 78 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f" %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter))) 79 | 80 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 81 | eval_loss,eval_acc_intent,eval_acc_slot = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size) 82 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:",eval_acc_intent,";acc_slot:",eval_acc_slot) 83 | if eval_loss > previous_eval_loss: # if loss is not decreasing 84 | # reduce the learning rate by a factor of 0.5 85 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 86 | learning_rate1 = sess.run(model.learning_rate) 87 | lrr = sess.run([model.learning_rate_decay_half_op]) 88 | learning_rate2 = sess.run(model.learning_rate) 89 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 90 | else: # loss is decreasing 91 | if eval_loss < best_eval_loss: 92 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 93 | # save model to checkpoint 94 | save_path = FLAGS.ckpt_dir + "model.ckpt" 95 | saver.save(sess, save_path, global_step=epoch) 96 | best_eval_loss = eval_loss 97 | previous_eval_loss = eval_loss 98 | 99 | # epoch increment 100 | print("going to increment epoch counter....") 101 | sess.run(model.epoch_increment) 102 | 103 | # 5.最后在测试集上做测试,并报告测试准确率 Test 104 | test_loss, test_acc_intent,test_acc_slot = do_eval(sess, model, x_test, y_intent_test, y_slots_test, batch_size) 105 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot) 106 | pass 107 | 108 | # 在验证集上做验证,报告损失、精确度 109 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid, batch_size): 110 | number_examples = len(x_valid) 111 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = 0.0,0.0, 0.0, 0 112 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 113 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 114 | feed_dict[model.y_intent] = y_intent_valid[start:end] 115 | feed_dict[model.y_slots] = y_slots_valid[start:end] 116 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot],feed_dict) 117 | eval_loss, eval_acc_intent,eval_acc_slot, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , eval_acc_slot+curr_eval_acc_slot,eval_counter + 1 118 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter) 119 | 120 | if __name__ == "__main__": 121 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v6_with_domain_knowledge/joint_intent_slots_knowledge_domain_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_domain_model import joint_knowledge_domain_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data _10w.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes,domain_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train,y_domain_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid,y_domain_valid = valid_data 39 | x_test, y_intent_test, y_slots_test,y_domain_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_domain_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training,domain_num_classes) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, acc_domain,counter = 0.0,0.0, 0.0, 0.0,0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_domain_train[start:end]:", y_domain_train[0:3]) 72 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 73 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 74 | feed_dict[model.y_intent] = y_intent_train[start:end] 75 | feed_dict[model.y_domain] = y_domain_train[start:end] 76 | feed_dict[model.y_slots] = y_slots_train[start:end] 77 | curr_loss, curr_acc_intent,curr_acc_slot,curr_acc_domain, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain, model.train_op],feed_dict) 78 | loss, counter, acc_intent,acc_slot,acc_domain = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot,acc_domain+curr_acc_domain 79 | if counter % 50 == 0: 80 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f\tTrain Accuracy_domain:%.3f" 81 | %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter),acc_domain/float(counter))) 82 | 83 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 84 | eval_loss,eval_acc_intent,eval_acc_slot,eval_acc_domain = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size) 85 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:", 86 | eval_acc_intent,";acc_slot:",eval_acc_slot,";acc_domain:",eval_acc_domain) 87 | if eval_loss > previous_eval_loss: # if loss is not decreasing 88 | # reduce the learning rate by a factor of 0.5 89 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 90 | learning_rate1 = sess.run(model.learning_rate) 91 | lrr = sess.run([model.learning_rate_decay_half_op]) 92 | learning_rate2 = sess.run(model.learning_rate) 93 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 94 | else: # loss is decreasing 95 | if eval_loss < best_eval_loss: 96 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 97 | # save model to checkpoint 98 | save_path = FLAGS.ckpt_dir + "model.ckpt" 99 | saver.save(sess, save_path, global_step=epoch) 100 | best_eval_loss = eval_loss 101 | previous_eval_loss = eval_loss 102 | 103 | # epoch increment 104 | print("going to increment epoch counter....") 105 | sess.run(model.epoch_increment) 106 | 107 | # 5.最后在测试集上做测试,并报告测试准确率 Test 108 | test_loss, test_acc_intent,test_acc_slot,test_acc_domain = do_eval(sess, model, x_test, y_intent_test, y_slots_test,y_domain_test, batch_size) 109 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot,";test_acc_domain:",test_acc_domain) 110 | pass 111 | 112 | # 在验证集上做验证,报告损失、精确度 113 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size): 114 | number_examples = len(x_valid) 115 | eval_loss, eval_acc_intent,eval_acc_slot, eval_acc_domain,eval_counter = 0.0,0.0,0.0, 0.0, 0 116 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 117 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 118 | feed_dict[model.y_intent] = y_intent_valid[start:end] 119 | feed_dict[model.y_domain] = y_domain_valid[start:end] 120 | feed_dict[model.y_slots] = y_slots_valid[start:end] 121 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot,curr_eval_acc_domain = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain],feed_dict) 122 | eval_loss, eval_acc_intent,eval_acc_slot,eval_acc_domain, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , \ 123 | eval_acc_slot+curr_eval_acc_slot,eval_acc_domain+curr_eval_acc_domain,eval_counter + 1 124 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter),eval_acc_domain/float(eval_counter) 125 | 126 | if __name__ == "__main__": 127 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v7_with_domain_knowledge_context_window/joint_intent_slots_knowledge_domain_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_domain_model import joint_knowledge_domain_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data _10w.txt","file for data source") #knowledge/sht_20171125.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes,domain_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train,y_domain_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid,y_domain_valid = valid_data 39 | x_test, y_intent_test, y_slots_test,y_domain_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_domain_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training,domain_num_classes) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, acc_domain,counter = 0.0,0.0, 0.0, 0.0,0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_domain_train[start:end]:", y_domain_train[0:3]) 72 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 73 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 74 | feed_dict[model.y_intent] = y_intent_train[start:end] 75 | feed_dict[model.y_domain] = y_domain_train[start:end] 76 | feed_dict[model.y_slots] = y_slots_train[start:end] 77 | curr_loss, curr_acc_intent,curr_acc_slot,curr_acc_domain, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain, model.train_op],feed_dict) 78 | loss, counter, acc_intent,acc_slot,acc_domain = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot,acc_domain+curr_acc_domain 79 | if counter % 50 == 0: 80 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f\tTrain Accuracy_domain:%.3f" 81 | %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter),acc_domain/float(counter))) 82 | 83 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 84 | eval_loss,eval_acc_intent,eval_acc_slot,eval_acc_domain = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size) 85 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:", 86 | eval_acc_intent,";acc_slot:",eval_acc_slot,";acc_domain:",eval_acc_domain) 87 | if eval_loss > previous_eval_loss: # if loss is not decreasing 88 | # reduce the learning rate by a factor of 0.5 89 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 90 | learning_rate1 = sess.run(model.learning_rate) 91 | lrr = sess.run([model.learning_rate_decay_half_op]) 92 | learning_rate2 = sess.run(model.learning_rate) 93 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 94 | else: # loss is decreasing 95 | if eval_loss < best_eval_loss: 96 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 97 | # save model to checkpoint 98 | save_path = FLAGS.ckpt_dir + "model.ckpt" 99 | saver.save(sess, save_path, global_step=epoch) 100 | best_eval_loss = eval_loss 101 | previous_eval_loss = eval_loss 102 | 103 | # epoch increment 104 | print("going to increment epoch counter....") 105 | sess.run(model.epoch_increment) 106 | 107 | # 5.最后在测试集上做测试,并报告测试准确率 Test 108 | test_loss, test_acc_intent,test_acc_slot,test_acc_domain = do_eval(sess, model, x_test, y_intent_test, y_slots_test,y_domain_test, batch_size) 109 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot,";test_acc_domain:",test_acc_domain) 110 | pass 111 | 112 | # 在验证集上做验证,报告损失、精确度 113 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size): 114 | number_examples = len(x_valid) 115 | eval_loss, eval_acc_intent,eval_acc_slot, eval_acc_domain,eval_counter = 0.0,0.0,0.0, 0.0, 0 116 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 117 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 118 | feed_dict[model.y_intent] = y_intent_valid[start:end] 119 | feed_dict[model.y_domain] = y_domain_valid[start:end] 120 | feed_dict[model.y_slots] = y_slots_valid[start:end] 121 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot,curr_eval_acc_domain = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain],feed_dict) 122 | eval_loss, eval_acc_intent,eval_acc_slot,eval_acc_domain, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , \ 123 | eval_acc_slot+curr_eval_acc_slot,eval_acc_domain+curr_eval_acc_domain,eval_counter + 1 124 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter),eval_acc_domain/float(eval_counter) 125 | 126 | if __name__ == "__main__": 127 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v8_slot_condition_intent/joint_intent_slots_knowledge_conditional_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | import os 10 | from joint_intent_slots_knowledge_conditional_model import joint_knowledge_conditional_model 11 | from a1_data_util import generate_training_data 12 | import jieba 13 | 14 | #configuration 15 | FLAGS=tf.app.flags.FLAGS 16 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 17 | tf.app.flags.DEFINE_integer("batch_size", 64, "Batch size for training/evaluating.") #批处理的大小 32-->128 18 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 19 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 20 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 21 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #15 22 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 23 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 24 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 25 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 26 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 27 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 28 | 29 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data_1w.txt","file for data source") #knowledge_67800/training_data_38_50w.txt 30 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 31 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 32 | 33 | 34 | def main(_): 35 | #1. load data 36 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes,domain_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 37 | x_train, y_intent_train, y_slots_train,y_domain_train=traing_data 38 | x_valid, y_intent_valid, y_slots_valid,y_domain_valid = valid_data 39 | x_test, y_intent_test, y_slots_test,y_domain_test = test_data 40 | 41 | # 2.create session. 42 | config = tf.ConfigProto() 43 | config.gpu_options.allow_growth = True 44 | with tf.Session(config=config) as sess: 45 | # Instantiate Model 46 | sequence_length_batch=[FLAGS.sequence_length]*FLAGS.batch_size 47 | model=joint_knowledge_conditional_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, FLAGS.sequence_length, 48 | vocab_size, FLAGS.embed_size,FLAGS.hidden_size, sequence_length_batch,slots_num_classes,FLAGS.is_training,domain_num_classes) 49 | # Initialize Save 50 | saver = tf.train.Saver() 51 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 52 | print("Restoring Variables from Checkpoint") 53 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 54 | else: 55 | print('Initializing Variables') 56 | sess.run(tf.global_variables_initializer()) 57 | curr_epoch = sess.run(model.epoch_step) 58 | # 3.feed data & training 59 | number_of_training_data = len(x_train) 60 | print("number_of_training_data:", number_of_training_data) 61 | previous_eval_loss = 10000 62 | best_eval_loss = 10000 63 | batch_size = FLAGS.batch_size 64 | for epoch in range(curr_epoch, FLAGS.num_epochs): 65 | loss, acc_intent,acc_slot, acc_domain,counter = 0.0,0.0, 0.0, 0.0,0 66 | for start, end in zip(range(0, number_of_training_data, batch_size), 67 | range(batch_size, number_of_training_data, batch_size)): 68 | if epoch == 0 and counter == 0:#print sample to have a look 69 | print("trainX[start:end]:", x_train[0:3]) 70 | print("y_intent_train[start:end]:", y_intent_train[0:3]) 71 | print("y_domain_train[start:end]:", y_domain_train[0:3]) 72 | print("y_slots_train[start:end]:", y_slots_train[0:3]) 73 | feed_dict = {model.x: x_train[start:end], model.dropout_keep_prob: 0.5} 74 | feed_dict[model.y_intent] = y_intent_train[start:end] 75 | feed_dict[model.y_domain] = y_domain_train[start:end] 76 | feed_dict[model.y_slots] = y_slots_train[start:end] 77 | curr_loss, curr_acc_intent,curr_acc_slot,curr_acc_domain, _ = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain, model.train_op],feed_dict) 78 | loss, counter, acc_intent,acc_slot,acc_domain = loss + curr_loss, counter + 1, acc_intent + curr_acc_intent,acc_slot+curr_acc_slot,acc_domain+curr_acc_domain 79 | if counter % 50 == 0: 80 | print("joint_intent_slots_knowledge_model==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy_intent:%.3f\tTrain Accuracy_slot:%.3f\tTrain Accuracy_domain:%.3f" 81 | %(epoch, counter, loss / float(counter),acc_intent / float(counter),acc_slot / float(counter),acc_domain/float(counter))) 82 | 83 | if start==0 or start % (FLAGS.validate_step * FLAGS.batch_size) == 0:#evaluation. 84 | eval_loss,eval_acc_intent,eval_acc_slot,eval_acc_domain = do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size) 85 | print("joint_intent_slots_knowledge_model.validation.part. previous_eval_loss:",previous_eval_loss ,";current_eval_loss:",eval_loss,";acc_intent:", 86 | eval_acc_intent,";acc_slot:",eval_acc_slot,";acc_domain:",eval_acc_domain) 87 | if eval_loss > previous_eval_loss: # if loss is not decreasing 88 | # reduce the learning rate by a factor of 0.5 89 | print("joint_intent_slots_knowledge_model==>validation.part.going to reduce the learning rate.") 90 | learning_rate1 = sess.run(model.learning_rate) 91 | lrr = sess.run([model.learning_rate_decay_half_op]) 92 | learning_rate2 = sess.run(model.learning_rate) 93 | print("joint_intent_slots_knowledge_model==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 94 | else: # loss is decreasing 95 | if eval_loss < best_eval_loss: 96 | print("joint_intent_slots_knowledge_model==>going to save the model.eval_loss:",eval_loss, ";best_eval_loss:",best_eval_loss) 97 | # save model to checkpoint 98 | save_path = FLAGS.ckpt_dir + "model.ckpt" 99 | saver.save(sess, save_path, global_step=epoch) 100 | best_eval_loss = eval_loss 101 | previous_eval_loss = eval_loss 102 | 103 | # epoch increment 104 | print("going to increment epoch counter....") 105 | sess.run(model.epoch_increment) 106 | 107 | # 5.最后在测试集上做测试,并报告测试准确率 Test 108 | test_loss, test_acc_intent,test_acc_slot,test_acc_domain = do_eval(sess, model, x_test, y_intent_test, y_slots_test,y_domain_test, batch_size) 109 | print("test_loss:",test_loss,";test_acc_intent:",test_acc_intent,";test_acc_slot:",test_acc_slot,";test_acc_domain:",test_acc_domain) 110 | pass 111 | 112 | # 在验证集上做验证,报告损失、精确度 113 | def do_eval(sess, model, x_valid, y_intent_valid, y_slots_valid,y_domain_valid, batch_size): 114 | number_examples = len(x_valid) 115 | eval_loss, eval_acc_intent,eval_acc_slot, eval_acc_domain,eval_counter = 0.0,0.0,0.0, 0.0, 0 116 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 117 | feed_dict = {model.x: x_valid[start:end], model.dropout_keep_prob: 1.0} 118 | feed_dict[model.y_intent] = y_intent_valid[start:end] 119 | feed_dict[model.y_domain] = y_domain_valid[start:end] 120 | feed_dict[model.y_slots] = y_slots_valid[start:end] 121 | curr_eval_loss, curr_eval_acc_intent,curr_eval_acc_slot,curr_eval_acc_domain = sess.run([model.loss_val, model.accuracy_intent,model.accuracy_slot,model.accuracy_domain],feed_dict) 122 | eval_loss, eval_acc_intent,eval_acc_slot,eval_acc_domain, eval_counter = eval_loss + curr_eval_loss, eval_acc_intent +curr_eval_acc_intent , \ 123 | eval_acc_slot+curr_eval_acc_slot,eval_acc_domain+curr_eval_acc_domain,eval_counter + 1 124 | return eval_loss / float(eval_counter), eval_acc_intent / float(eval_counter),eval_acc_slot / float(eval_counter),eval_acc_domain/float(eval_counter) 125 | 126 | if __name__ == "__main__": 127 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v5_without_knowledge/joint_intent_slots_knowledge_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_model import joint_knowledge_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 35 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 36 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 37 | 38 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 39 | 40 | #create session and load the model from checkpoint 41 | # load vocabulary for intent and slot name 42 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 43 | id2word = {value: key for key, value in word2id.items()} 44 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 45 | id2word_intent = {value: key for key, value in word2id_intent.items()} 46 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 47 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 48 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 49 | 50 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 51 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 52 | 53 | intent_num_classes=len(word2id_intent) 54 | vocab_size=len(word2id) 55 | slots_num_classes=len(id2word_slotname) 56 | 57 | config = tf.ConfigProto() 58 | config.gpu_options.allow_growth = True 59 | sess = tf.Session(config=config) 60 | FLAGS.batch_size = 1 61 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 62 | model = joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 63 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 64 | sequence_length_batch, slots_num_classes, FLAGS.is_training,S_Q_len=len(q_list_index)) 65 | # initialize Saver 66 | saver = tf.train.Saver() 67 | print('restoring Variables from Checkpoint!') 68 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 69 | 70 | 71 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 72 | jieba.load_userdict(slot_values_file) 73 | 74 | def main(_): 75 | sentence=u'开灯' #u'帮我打开厕所的灯' 76 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 77 | intent,intent_logits, slots,slot_list,similiarity_list_result=predict(sentence) 78 | print(sentence) 79 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 80 | #for slot_name,slot_value in slots.items(): 81 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 82 | for i,element in enumerate(slot_list): 83 | slot_name,slot_value=element 84 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 85 | 86 | accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 87 | print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 88 | 89 | predict_interactive() 90 | 91 | 92 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 93 | #1.get validation set 94 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 95 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 96 | #2.loop each data 97 | count_similiarity_right=0 98 | count_classification_right=0 99 | len_validation=len(dict_pair) 100 | 101 | i=0 102 | for sentence,value in dict_pair.items(): 103 | #3.call predict 104 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 105 | y_intent_target=value['intent'] 106 | similiar_intent=similiarity_list_result[0] 107 | if similiar_intent ==y_intent_target: 108 | count_similiarity_right+=1 109 | if intent==y_intent_target: 110 | count_classification_right+=1 111 | if i%10==0: 112 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 113 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 114 | i=i+1 115 | #4.get accuracy 116 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 117 | accuracy_classification = float(count_classification_right) / float(len_validation) 118 | 119 | return accuracy_similiarity,accuracy_classification 120 | 121 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 122 | #1.get validation set 123 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 124 | x_valid, y_intent_valid, y_slots_valid = valid_data 125 | #2.loop each data 126 | count_similiarity_right=0 127 | count_classification_right=0 128 | len_validation=len(x_valid) 129 | for i, x_indices in enumerate(x_valid): 130 | y_intent=y_intent_valid[i] 131 | sentence=get_sentence_from_index(x_indices) 132 | #3.call predict 133 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 134 | y_intent_target=id2word_intent[y_intent] 135 | similiar_intent=similiarity_list_result[0] 136 | if similiar_intent ==y_intent_target: 137 | count_similiarity_right+=1 138 | if intent==y_intent_target: 139 | count_classification_right+=1 140 | if i%10==0: 141 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 142 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 143 | #4.get accuracy 144 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 145 | accuracy_classification = float(count_classification_right) / float(len_validation) 146 | 147 | return accuracy_similiarity,accuracy_classification 148 | 149 | def get_sentence_from_index(x_indices): 150 | sentence=[ id2word.get(index,UNK) for index in x_indices] 151 | sentence="".join(sentence) 152 | return sentence 153 | 154 | def predict(sentence,enable_knowledge=1): 155 | """ 156 | :param sentence: a sentence. 157 | :return: intent and slots 158 | """ 159 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 160 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 161 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 162 | #print("predict.y_slots:",y_slots) 163 | qa_list_length=len(q_list_index) 164 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 165 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 166 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 167 | model.dropout_keep_prob:1.0} 168 | logits_intent,logits_slots,similiarity_list = sess.run([model.logits_intent,model.logits_slots,model.similiarity_list], feed_dict) #similiarity_list:[1,None] 169 | intent,intent_logits,slots,slot_list,similiarity_list_result=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list) 170 | return intent,intent_logits,slots,slot_list,similiarity_list_result 171 | 172 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 173 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 174 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 175 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 176 | result=[word2id_slotname[O]]*sequence_length 177 | if enable_knowledge=='1' or enable_knowledge==1: 178 | for i,word in enumerate(user_speech_tokenized): 179 | slot_name=knowledge_dict.get(word,None) 180 | ##TODO print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 181 | if slot_name is not None: 182 | try: 183 | result[i]=word2id_slotname[slot_name] 184 | except: 185 | pass 186 | return result 187 | 188 | def predict_interactive(): 189 | sys.stdout.write("Please Input Story.>") 190 | sys.stdout.flush() 191 | question = sys.stdin.readline() 192 | enable_knowledge=1 193 | while question: 194 | if question.find("disable_knowledge")>=0: 195 | enable_knowledge=0 196 | print("knowledge disabled") 197 | print("Please Input Story>") 198 | sys.stdout.flush() 199 | question = sys.stdin.readline() 200 | elif question.find("enable_knowledge")>=0: 201 | enable_knowledge=1 202 | #3.read new input 203 | print("knowledge enabled") 204 | print("Please Input Story>") 205 | sys.stdout.flush() 206 | question = sys.stdin.readline() 207 | 208 | #1.predict using quesiton 209 | intent, intent_logits,slots,slot_list,similiarity_list=predict(question,enable_knowledge=enable_knowledge) 210 | #2.print 211 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 212 | #for i,similiarity in enumerate(similiarity_list): 213 | # print('i:{},similiarity:{}'.format(i, similiarity)) 214 | #for slot_name, slot_value in slots.items(): 215 | # print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 216 | for i, element in enumerate(slot_list): 217 | slot_name, slot_value = element 218 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 219 | #3.read new input 220 | print("Please Input Story>") 221 | sys.stdout.flush() 222 | question = sys.stdin.readline() 223 | 224 | 225 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,top_number=3): 226 | index_intent= np.argmax(logits_intent[0]) #index of intent 227 | intent_logits=logits_intent[0][index_intent] 228 | #print("intent_logits:",index_intent) 229 | intent=id2word_intent[index_intent] 230 | 231 | slots=[] 232 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 233 | for i,index in enumerate(indices_slots): 234 | slots.append(id2word_slotname[index]) 235 | slots_dict={} 236 | slot_list=[] 237 | for i,slot in enumerate(slots): 238 | word=id2word[sentence_indices[i]] 239 | #print(i,"slot:",slot,";word:",word) 240 | if slot!=O and word!=PAD and word!=UNK: 241 | slots_dict[slot]=word 242 | slot_list.append((slot,word)) 243 | 244 | #get top answer for the similiarity list. 245 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 246 | similiarity_list_top = similiarity_list_top[::-1] 247 | similiarity_list_result=[] 248 | for k,index in enumerate(similiarity_list_top): 249 | question=q_list[index] 250 | answer=q2a_dict[question] 251 | similiarity_list_result.append(answer) 252 | #TODO print('similiarity.index:{} question:{}, answer:{}'.format(k,question, answer)) 253 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result 254 | 255 | if __name__ == "__main__": 256 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v3_bi_directional_cnn_tmall/joint_intent_slots_knowledge_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_model import joint_knowledge_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 35 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 36 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 37 | 38 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 39 | 40 | #create session and load the model from checkpoint 41 | # load vocabulary for intent and slot name 42 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 43 | id2word = {value: key for key, value in word2id.items()} 44 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 45 | id2word_intent = {value: key for key, value in word2id_intent.items()} 46 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 47 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 48 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 49 | 50 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 51 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 52 | 53 | intent_num_classes=len(word2id_intent) 54 | vocab_size=len(word2id) 55 | slots_num_classes=len(id2word_slotname) 56 | 57 | config = tf.ConfigProto() 58 | config.gpu_options.allow_growth = True 59 | sess = tf.Session(config=config) 60 | FLAGS.batch_size = 1 61 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 62 | model = joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 63 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 64 | sequence_length_batch, slots_num_classes, FLAGS.is_training,S_Q_len=len(q_list_index)) 65 | # initialize Saver 66 | saver = tf.train.Saver() 67 | print('restoring Variables from Checkpoint!') 68 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 69 | 70 | 71 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 72 | jieba.load_userdict(slot_values_file) 73 | 74 | def main(_): 75 | sentence=u'开灯' #u'帮我打开厕所的灯' 76 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 77 | intent,intent_logits, slots,slot_list,similiarity_list_result=predict(sentence) 78 | print(sentence) 79 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 80 | #for slot_name,slot_value in slots.items(): 81 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 82 | for i,element in enumerate(slot_list): 83 | slot_name,slot_value=element 84 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 85 | 86 | accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 87 | print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 88 | 89 | predict_interactive() 90 | 91 | 92 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 93 | #1.get validation set 94 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 95 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 96 | #2.loop each data 97 | count_similiarity_right=0 98 | count_classification_right=0 99 | len_validation=len(dict_pair) 100 | 101 | i=0 102 | for sentence,value in dict_pair.items(): 103 | #3.call predict 104 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 105 | y_intent_target=value['intent'] 106 | similiar_intent=similiarity_list_result[0] 107 | if similiar_intent ==y_intent_target: 108 | count_similiarity_right+=1 109 | if intent==y_intent_target: 110 | count_classification_right+=1 111 | if i%10==0: 112 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 113 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 114 | i=i+1 115 | #4.get accuracy 116 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 117 | accuracy_classification = float(count_classification_right) / float(len_validation) 118 | 119 | return accuracy_similiarity,accuracy_classification 120 | 121 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 122 | #1.get validation set 123 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 124 | x_valid, y_intent_valid, y_slots_valid = valid_data 125 | #2.loop each data 126 | count_similiarity_right=0 127 | count_classification_right=0 128 | len_validation=len(x_valid) 129 | for i, x_indices in enumerate(x_valid): 130 | y_intent=y_intent_valid[i] 131 | sentence=get_sentence_from_index(x_indices) 132 | #3.call predict 133 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 134 | y_intent_target=id2word_intent[y_intent] 135 | similiar_intent=similiarity_list_result[0] 136 | if similiar_intent ==y_intent_target: 137 | count_similiarity_right+=1 138 | if intent==y_intent_target: 139 | count_classification_right+=1 140 | if i%10==0: 141 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 142 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 143 | #4.get accuracy 144 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 145 | accuracy_classification = float(count_classification_right) / float(len_validation) 146 | 147 | return accuracy_similiarity,accuracy_classification 148 | 149 | def get_sentence_from_index(x_indices): 150 | sentence=[ id2word.get(index,UNK) for index in x_indices] 151 | sentence="".join(sentence) 152 | return sentence 153 | 154 | def predict(sentence,enable_knowledge=1): 155 | """ 156 | :param sentence: a sentence. 157 | :return: intent and slots 158 | """ 159 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 160 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 161 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 162 | #print("predict.y_slots:",y_slots) 163 | qa_list_length=len(q_list_index) 164 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 165 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 166 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 167 | model.dropout_keep_prob:1.0} 168 | logits_intent,logits_slots,similiarity_list = sess.run([model.logits_intent,model.logits_slots,model.similiarity_list], feed_dict) #similiarity_list:[1,None] 169 | intent,intent_logits,slots,slot_list,similiarity_list_result=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list) 170 | return intent,intent_logits,slots,slot_list,similiarity_list_result 171 | 172 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 173 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 174 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 175 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 176 | result=[word2id_slotname[O]]*sequence_length 177 | if enable_knowledge=='1' or enable_knowledge==1: 178 | for i,word in enumerate(user_speech_tokenized): 179 | slot_name=knowledge_dict.get(word,None) 180 | ##TODO print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 181 | if slot_name is not None: 182 | try: 183 | result[i]=word2id_slotname[slot_name] 184 | except: 185 | pass 186 | return result 187 | 188 | def predict_interactive(): 189 | sys.stdout.write("Please Input Story.>") 190 | sys.stdout.flush() 191 | question = sys.stdin.readline() 192 | enable_knowledge=1 193 | while question: 194 | if question.find("disable_knowledge")>=0: 195 | enable_knowledge=0 196 | print("knowledge disabled") 197 | print("Please Input Story>") 198 | sys.stdout.flush() 199 | question = sys.stdin.readline() 200 | elif question.find("enable_knowledge")>=0: 201 | enable_knowledge=1 202 | #3.read new input 203 | print("knowledge enabled") 204 | print("Please Input Story>") 205 | sys.stdout.flush() 206 | question = sys.stdin.readline() 207 | 208 | #1.predict using quesiton 209 | intent, intent_logits,slots,slot_list,similiarity_list=predict(question,enable_knowledge=enable_knowledge) 210 | #2.print 211 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 212 | #for i,similiarity in enumerate(similiarity_list): 213 | # print('i:{},similiarity:{}'.format(i, similiarity)) 214 | #for slot_name, slot_value in slots.items(): 215 | # print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 216 | for i, element in enumerate(slot_list): 217 | slot_name, slot_value = element 218 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 219 | #3.read new input 220 | print("Please Input Story>") 221 | sys.stdout.flush() 222 | question = sys.stdin.readline() 223 | 224 | 225 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,top_number=3): 226 | index_intent= np.argmax(logits_intent[0]) #index of intent 227 | intent_logits=logits_intent[0][index_intent] 228 | #print("intent_logits:",index_intent) 229 | intent=id2word_intent[index_intent] 230 | 231 | slots=[] 232 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 233 | for i,index in enumerate(indices_slots): 234 | slots.append(id2word_slotname[index]) 235 | slots_dict={} 236 | slot_list=[] 237 | for i,slot in enumerate(slots): 238 | word=id2word[sentence_indices[i]] 239 | #print(i,"slot:",slot,";word:",word) 240 | if slot!=O and word!=PAD and word!=UNK: 241 | slots_dict[slot]=word 242 | slot_list.append((slot,word)) 243 | 244 | #get top answer for the similiarity list. 245 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 246 | similiarity_list_top = similiarity_list_top[::-1] 247 | similiarity_list_result=[] 248 | for k,index in enumerate(similiarity_list_top): 249 | question=q_list[index] 250 | answer=q2a_dict[question] 251 | similiarity_list_result.append(answer) 252 | #TODO print('similiarity.index:{} question:{}, answer:{}'.format(k,question, answer)) 253 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result 254 | 255 | if __name__ == "__main__": 256 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v4_cnn_with_symbol_alime/joint_intent_slots_knowledge_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_model import joint_knowledge_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_skill3/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_skill3","file for data source") #skill3_train_20171114.txt 35 | tf.app.flags.DEFINE_string("data_source","knowledge_skill3/skill3_train_20171114.txt","file for data source") #knowledge/sht_20171125.txt 36 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 37 | 38 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 39 | 40 | #create session and load the model from checkpoint 41 | # load vocabulary for intent and slot name 42 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 43 | id2word = {value: key for key, value in word2id.items()} 44 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 45 | id2word_intent = {value: key for key, value in word2id_intent.items()} 46 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 47 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 48 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 49 | 50 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 51 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 52 | 53 | intent_num_classes=len(word2id_intent) 54 | vocab_size=len(word2id) 55 | slots_num_classes=len(id2word_slotname) 56 | 57 | config = tf.ConfigProto() 58 | config.gpu_options.allow_growth = True 59 | sess = tf.Session(config=config) 60 | FLAGS.batch_size = 1 61 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 62 | model = joint_knowledge_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 63 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 64 | sequence_length_batch, slots_num_classes, FLAGS.is_training,S_Q_len=len(q_list_index)) 65 | # initialize Saver 66 | saver = tf.train.Saver() 67 | print('restoring Variables from Checkpoint!') 68 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 69 | 70 | 71 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 72 | jieba.load_userdict(slot_values_file) 73 | 74 | def main(_): 75 | sentence=u'开灯' #u'帮我打开厕所的灯' 76 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 77 | intent,intent_logits, slots,slot_list,similiarity_list_result=predict(sentence) 78 | print(sentence) 79 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 80 | #for slot_name,slot_value in slots.items(): 81 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 82 | for i,element in enumerate(slot_list): 83 | slot_name,slot_value=element 84 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 85 | 86 | accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 87 | print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 88 | 89 | predict_interactive() 90 | 91 | 92 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 93 | #1.get validation set 94 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 95 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 96 | #2.loop each data 97 | count_similiarity_right=0 98 | count_classification_right=0 99 | len_validation=len(dict_pair) 100 | 101 | i=0 102 | for sentence,value in dict_pair.items(): 103 | #3.call predict 104 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 105 | y_intent_target=value['intent'] 106 | similiar_intent=similiarity_list_result[0] 107 | if similiar_intent ==y_intent_target: 108 | count_similiarity_right+=1 109 | if intent==y_intent_target: 110 | count_classification_right+=1 111 | if i%10==0: 112 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 113 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 114 | i=i+1 115 | #4.get accuracy 116 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 117 | accuracy_classification = float(count_classification_right) / float(len_validation) 118 | 119 | return accuracy_similiarity,accuracy_classification 120 | 121 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 122 | #1.get validation set 123 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 124 | x_valid, y_intent_valid, y_slots_valid = valid_data 125 | #2.loop each data 126 | count_similiarity_right=0 127 | count_classification_right=0 128 | len_validation=len(x_valid) 129 | for i, x_indices in enumerate(x_valid): 130 | y_intent=y_intent_valid[i] 131 | sentence=get_sentence_from_index(x_indices) 132 | #3.call predict 133 | intent, intent_logits, slots, slot_list, similiarity_list_result = predict(sentence) 134 | y_intent_target=id2word_intent[y_intent] 135 | similiar_intent=similiarity_list_result[0] 136 | if similiar_intent ==y_intent_target: 137 | count_similiarity_right+=1 138 | if intent==y_intent_target: 139 | count_classification_right+=1 140 | if i%10==0: 141 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 142 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 143 | #4.get accuracy 144 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 145 | accuracy_classification = float(count_classification_right) / float(len_validation) 146 | 147 | return accuracy_similiarity,accuracy_classification 148 | 149 | def get_sentence_from_index(x_indices): 150 | sentence=[ id2word.get(index,UNK) for index in x_indices] 151 | sentence="".join(sentence) 152 | return sentence 153 | 154 | def predict(sentence,enable_knowledge=1): 155 | """ 156 | :param sentence: a sentence. 157 | :return: intent and slots 158 | """ 159 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 160 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 161 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 162 | #print("predict.y_slots:",y_slots) 163 | qa_list_length=len(q_list_index) 164 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 165 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 166 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 167 | model.dropout_keep_prob:1.0} 168 | logits_intent,logits_slots,similiarity_list = sess.run([model.logits_intent,model.logits_slots,model.similiarity_list], feed_dict) #similiarity_list:[1,None] 169 | intent,intent_logits,slots,slot_list,similiarity_list_result=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list) 170 | return intent,intent_logits,slots,slot_list,similiarity_list_result 171 | 172 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 173 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 174 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 175 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 176 | result=[word2id_slotname[O]]*sequence_length 177 | if enable_knowledge=='1' or enable_knowledge==1: 178 | for i,word in enumerate(user_speech_tokenized): 179 | slot_name=knowledge_dict.get(word,None) 180 | ##TODO print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 181 | if slot_name is not None: 182 | try: 183 | result[i]=word2id_slotname[slot_name] 184 | except: 185 | pass 186 | return result 187 | 188 | def predict_interactive(): 189 | sys.stdout.write("Please Input Story.>") 190 | sys.stdout.flush() 191 | question = sys.stdin.readline() 192 | enable_knowledge=1 193 | while question: 194 | if question.find("disable_knowledge")>=0: 195 | enable_knowledge=0 196 | print("knowledge disabled") 197 | print("Please Input Story>") 198 | sys.stdout.flush() 199 | question = sys.stdin.readline() 200 | elif question.find("enable_knowledge")>=0: 201 | enable_knowledge=1 202 | #3.read new input 203 | print("knowledge enabled") 204 | print("Please Input Story>") 205 | sys.stdout.flush() 206 | question = sys.stdin.readline() 207 | 208 | #1.predict using quesiton 209 | intent, intent_logits,slots,slot_list,similiarity_list=predict(question,enable_knowledge=enable_knowledge) 210 | #2.print 211 | print('intent:{},intent_logits:{}'.format(intent, intent_logits)) 212 | #for i,similiarity in enumerate(similiarity_list): 213 | # print('i:{},similiarity:{}'.format(i, similiarity)) 214 | #for slot_name, slot_value in slots.items(): 215 | # print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 216 | for i, element in enumerate(slot_list): 217 | slot_name, slot_value = element 218 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 219 | #3.read new input 220 | print("Please Input Story>") 221 | sys.stdout.flush() 222 | question = sys.stdin.readline() 223 | 224 | 225 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,top_number=3): 226 | index_intent= np.argmax(logits_intent[0]) #index of intent 227 | intent_logits=logits_intent[0][index_intent] 228 | #print("intent_logits:",index_intent) 229 | intent=id2word_intent[index_intent] 230 | 231 | slots=[] 232 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 233 | for i,index in enumerate(indices_slots): 234 | slots.append(id2word_slotname[index]) 235 | slots_dict={} 236 | slot_list=[] 237 | for i,slot in enumerate(slots): 238 | word=id2word[sentence_indices[i]] 239 | #print(i,"slot:",slot,";word:",word) 240 | if slot!=O and word!=PAD and word!=UNK: 241 | slots_dict[slot]=word 242 | slot_list.append((slot,word)) 243 | 244 | #get top answer for the similiarity list. 245 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 246 | similiarity_list_top = similiarity_list_top[::-1] 247 | similiarity_list_result=[] 248 | for k,index in enumerate(similiarity_list_top): 249 | question=q_list[index] 250 | answer=q2a_dict[question] 251 | similiarity_list_result.append(answer) 252 | #TODO print('similiarity.index:{} question:{}, answer:{}'.format(k,question, answer)) 253 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result 254 | 255 | if __name__ == "__main__": 256 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v0/a1_joint_intent_slots_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #training the model. 3 | #process--->1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | import tensorflow as tf 8 | import numpy as np 9 | from a1_seq2seq_attention_model import seq2seq_attention_model 10 | from data_util import load_data,load_vocab_as_dict 11 | from data_util_vocabulary import _build_vocab,_build_vocab_en 12 | import os,math 13 | import word2vec 14 | import pickle 15 | 16 | #configuration 17 | FLAGS=tf.app.flags.FLAGS 18 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 19 | tf.app.flags.DEFINE_integer("batch_size", 92, "Batch size for training/evaluating.") #批处理的大小 32-->128 20 | tf.app.flags.DEFINE_integer("decay_steps", 6000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 21 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 22 | tf.app.flags.DEFINE_string("ckpt_dir","ckpt_ai_challenger_translation/","checkpoint location for the model") 23 | tf.app.flags.DEFINE_integer("sequence_length",30,"max sentence length") #100 24 | tf.app.flags.DEFINE_integer("decoder_sent_length",30,"max sentence length") #100 25 | 26 | tf.app.flags.DEFINE_integer("embed_size",1000,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",True,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",20,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 6000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_boolean("use_embedding",True,"whether to use embedding or not.") 31 | tf.app.flags.DEFINE_string("word2vec_model_path","./data/ai_challenger_translation.bin-128","word2vec's vocabulary and vectors") #zhihu-word2vec.bin-100-->zhihu-word2vec-multilabel-minicount15.bin-100 32 | tf.app.flags.DEFINE_integer("hidden_size",1000,"hidden size") 33 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 34 | tf.app.flags.DEFINE_integer("vocabulary_size_en",60000,"vocabulary size of english") #100000 35 | tf.app.flags.DEFINE_integer("vocabulary_size_cn",100000,"vocabulary size of chinese") #100000 36 | tf.app.flags.DEFINE_string("data_folder","./data","path of traning data.") 37 | tf.app.flags.DEFINE_string("data_cn_path","./data/train.zh","path of traning data.") 38 | tf.app.flags.DEFINE_string("data_en_path","./data/train.en","path of traning data.") 39 | tf.app.flags.DEFINE_string("data_en_processed_path","./data/train.en.processed","path of traning data.") 40 | tf.app.flags.DEFINE_string("data_cn_valid_path","./data/valid.en-zh.zh.sgm","path of traning data.") 41 | tf.app.flags.DEFINE_string("data_en_valid_path","./data/valid.en-zh.en.sgm","path of traning data.") 42 | tf.app.flags.DEFINE_string("vocabulary_cn_path","./data/vocabulary.zh","path of traning data.") 43 | tf.app.flags.DEFINE_string("vocabulary_en_path","./data/vocabulary.en","path of traning data.") 44 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether it is test mode. if test mode, only use training size will be only 10,000.") 45 | 46 | #1.load data(X:list of lint,y:int). 2.create session. 3.feed data. 4.training (5.validation) ,(6.prediction) 47 | def main(_): 48 | #PART1############################################PREPARE DATA FOR TRAINING############################################ 49 | #1.create vocab 50 | #_build_vocab(FLAGS.data_en_path, FLAGS.vocabulary_en_path, FLAGS.vocabulary_size_en) 51 | _build_vocab_en(FLAGS.word2vec_model_path, FLAGS.vocabulary_en_path, FLAGS.vocabulary_size_en) 52 | _build_vocab(FLAGS.data_cn_path, FLAGS.vocabulary_cn_path, FLAGS.vocabulary_size_cn) 53 | #2.load vocab 54 | vocab_cn, vocab_en=load_vocab_as_dict(FLAGS.vocabulary_cn_path, FLAGS.vocabulary_en_path) 55 | vocab_en_index2word=dict([val,key] for key,val in vocab_en.items()) #get reverse order. 56 | #3.load data 57 | train,valid=load_data(FLAGS.data_folder, FLAGS.data_cn_path, FLAGS.data_en_path,FLAGS.data_en_processed_path, vocab_cn, vocab_en,FLAGS.data_cn_valid_path,FLAGS.data_en_valid_path,FLAGS.sequence_length,test_mode=FLAGS.test_mode) 58 | trainX, trainY_input,trainY_output = train 59 | testX, testY_input,testY_output = valid 60 | #4. print sample data 61 | print("trainX:", trainX[0:10]);print("trainY_input:",trainY_input[0:10]);print("trainY_output:",trainY_output[0:10]) 62 | print("testX:", testX[0:10]);print("testY_input:",testY_input[0:10]);print("testY_output:",testY_output[0:10]) 63 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 64 | # PART1############################################PREPARE DATA FOR TRAINING############################################# 65 | # PART2############################################TRAINING############################################################# 66 | # 2.create session. 67 | config = tf.ConfigProto() 68 | config.gpu_options.allow_growth = True 69 | with tf.Session(config=config) as sess: 70 | # Instantiate Model 71 | model = seq2seq_attention_model(len(vocab_cn), FLAGS.learning_rate, FLAGS.batch_size, FLAGS.decay_steps, 72 | FLAGS.decay_rate, FLAGS.sequence_length, len(vocab_en), FLAGS.embed_size, 73 | FLAGS.hidden_size, sequence_length_batch,FLAGS.is_training,decoder_sent_length=FLAGS.decoder_sent_length, l2_lambda=FLAGS.l2_lambda) 74 | # Initialize Save 75 | saver = tf.train.Saver() 76 | if os.path.exists(FLAGS.ckpt_dir + "checkpoint"): 77 | print("Restoring Variables from Checkpoint") 78 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 79 | else: 80 | print('Initializing Variables') 81 | sess.run(tf.global_variables_initializer()) 82 | if FLAGS.use_embedding: # load pre-trained word embedding 83 | assign_pretrained_word_embedding(sess, vocab_en_index2word, model,word2vec_model_path=FLAGS.word2vec_model_path) 84 | curr_epoch = sess.run(model.epoch_step) 85 | # 3.feed data & training 86 | number_of_training_data = len(trainX) 87 | print("number_of_training_data:", number_of_training_data) 88 | previous_eval_loss = 10000 89 | best_eval_loss = 10000 90 | batch_size = FLAGS.batch_size 91 | for epoch in range(curr_epoch, FLAGS.num_epochs): 92 | loss, acc, counter = 0.0, 0.0, 0 93 | for start, end in zip(range(0, number_of_training_data, batch_size), 94 | range(batch_size, number_of_training_data, batch_size)): 95 | if epoch == 0 and counter == 0:#print sample to have a look 96 | print("trainX[start:end]:", trainX[start:end]) 97 | feed_dict = {model.input_x: trainX[start:end], model.dropout_keep_prob: 0.5} 98 | feed_dict[model.decoder_input] = trainY_input[start:end] 99 | feed_dict[model.input_y_label] = trainY_output[start:end] 100 | curr_loss, curr_acc, _ = sess.run([model.loss_val, model.accuracy, model.train_op],feed_dict) 101 | loss, counter, acc = loss + curr_loss, counter + 1, acc + curr_acc 102 | if counter % 50 == 0: 103 | print("seq2seq_with_attention==>Epoch %d\tBatch %d\tTrain Loss:%.3f\tTrain Accuracy:%.3f" % 104 | (epoch, counter, math.exp(loss / float(counter)) if (loss / float(counter)) < 20 else 10000.000,acc / float(counter))) 105 | ##VALIDATION VALIDATION VALIDATION PART###################################################################################################### 106 | if start % (FLAGS.validate_step * FLAGS.batch_size) == 0: 107 | eval_loss, _ = do_eval(sess, model, testX, testY_input,testY_output, batch_size) 108 | print("seq2seq_with_attention.validation.part. previous_eval_loss:", 109 | math.exp(previous_eval_loss) if previous_eval_loss < 20 else 10000.000, ";current_eval_loss:", 110 | math.exp(eval_loss) if eval_loss < 20 else 10000.000) 111 | if eval_loss > previous_eval_loss: # if loss is not decreasing 112 | # reduce the learning rate by a factor of 0.5 113 | print("seq2seq_with_attention==>validation.part.going to reduce the learning rate.") 114 | learning_rate1 = sess.run(model.learning_rate) 115 | lrr = sess.run([model.learning_rate_decay_half_op]) 116 | learning_rate2 = sess.run(model.learning_rate) 117 | print("seq2seq_with_attention==>validation.part.learning_rate1:", learning_rate1," ;learning_rate2:", learning_rate2) 118 | else: # loss is decreasing 119 | if eval_loss < best_eval_loss: 120 | print("seq2seq_with_attention==>going to save the model.eval_loss:", 121 | math.exp(eval_loss) if eval_loss < 20 else 10000.000, ";best_eval_loss:", 122 | math.exp(best_eval_loss) if best_eval_loss < 20 else 10000.000) 123 | # save model to checkpoint 124 | save_path = FLAGS.ckpt_dir + "model.ckpt" 125 | saver.save(sess, save_path, global_step=epoch) 126 | best_eval_loss = eval_loss 127 | previous_eval_loss = eval_loss 128 | ##VALIDATION VALIDATION VALIDATION PART###################################################################################################### 129 | 130 | # epoch increment 131 | print("going to increment epoch counter....") 132 | sess.run(model.epoch_increment) 133 | 134 | # 5.最后在测试集上做测试,并报告测试准确率 Test 135 | #test_loss, test_acc = do_eval(sess, model, testX, testY, batch_size) 136 | pass 137 | # PART2############################################TRAINING############################################################# 138 | def assign_pretrained_word_embedding(sess, vocabulary_index2word, model, word2vec_model_path=None):#vocab_size 139 | """ 140 | assign pretrained word embedding to parameter of the model. 141 | :param sess: 142 | :param vocabulary_index2word: a dict of vocabulary of source side,{index:word}. in our experiment, it is a dict of english vocabulary 143 | :param vocab_size: 144 | :param model: 145 | :param word2vec_model_path: word-embedding path 146 | :return: no return, value assigned and applied to the parameter of the model 147 | """ 148 | print("using pre-trained word emebedding.started.word2vec_model_path:", word2vec_model_path) 149 | #1.load word-vector pair as dict, which was generated by word2vec 150 | word2vec_model = word2vec.load(word2vec_model_path, kind='bin') 151 | word2vec_dict = {} 152 | for word, vector in zip(word2vec_model.vocab, word2vec_model.vectors): 153 | word2vec_dict[word] = vector 154 | #2.assign vector for each word in vocabulary list; otherwise,init it. 155 | vocab_size=len(vocabulary_index2word) 156 | word_embedding_2dlist = [[]] * vocab_size # create an empty word_embedding list. 157 | word_embedding_2dlist[0] = np.zeros(FLAGS.embed_size) # assign empty for first word:'PAD' 158 | bound = np.sqrt(6.0) / np.sqrt(vocab_size) # bound for random variables. 159 | count_exist = 0; 160 | count_not_exist = 0 161 | for i in range(1, vocab_size): # loop each word 162 | word = vocabulary_index2word[i] # get a word 163 | embedding = None 164 | try: 165 | embedding = word2vec_dict[word] # try to get vector:it is an array. 166 | except Exception: 167 | embedding = None 168 | if embedding is not None: # the 'word' exist a embedding 169 | word_embedding_2dlist[i] = embedding 170 | count_exist = count_exist + 1 # assign array to this word. 171 | else:#no embedding for this word-->init it randomly. 172 | word_embedding_2dlist[i] = np.random.uniform(-bound, bound, FLAGS.embed_size); 173 | count_not_exist = count_not_exist + 1 # init a random value for the word. 174 | #3.assign(and invoke the operation) vocabulary list to variable of our model 175 | word_embedding_final = np.array(word_embedding_2dlist) # covert to 2d array. 176 | word_embedding = tf.constant(word_embedding_final, dtype=tf.float32) # convert to tensor 177 | t_assign_embedding = tf.assign(model.Embedding, 178 | word_embedding) # assign this value to our embedding variables of our model. 179 | sess.run(t_assign_embedding) 180 | print("word. exists embedding:", count_exist, " ;word not exist embedding:", count_not_exist) 181 | print("using pre-trained word emebedding.ended...") 182 | 183 | # 在验证集上做验证,报告损失、精确度 184 | def do_eval(sess, model, evalX, evalY_input,evalY_output, batch_size): 185 | number_examples = len(evalX) 186 | eval_loss, eval_acc, eval_counter = 0.0, 0.0, 0 187 | for start, end in zip(range(0, number_examples, batch_size), range(batch_size, number_examples, batch_size)): 188 | feed_dict = {model.input_x: evalX[start:end], model.dropout_keep_prob: 1.0} 189 | feed_dict[model.decoder_input] = evalY_input[start:end] 190 | feed_dict[model.input_y_label] = evalY_output[start:end] 191 | curr_eval_loss, logits, curr_eval_acc, pred = sess.run([model.loss_val, model.logits, model.accuracy, model.predictions],feed_dict) 192 | eval_loss, eval_acc, eval_counter = eval_loss + curr_eval_loss, eval_acc + curr_eval_acc, eval_counter + 1 193 | return eval_loss / float(eval_counter), eval_acc / float(eval_counter) 194 | 195 | 196 | 197 | if __name__ == "__main__": 198 | tf.app.run() 199 | 200 | 201 | if __name__ == "__main__": 202 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v7_with_domain_knowledge_context_window/joint_intent_slots_knowledge_domain_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_domain_model import joint_knowledge_domain_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 35 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data _10w.txt","file for data source") #knowledge/sht_20171125.txt 36 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 37 | 38 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 39 | 40 | # create session and load the model from checkpoint 41 | # load vocabulary for intent and slot name 42 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 43 | id2word = {value: key for key, value in word2id.items()} 44 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 45 | id2word_intent = {value: key for key, value in word2id_intent.items()} 46 | word2id_domain= create_or_load_vocabulary_domain(None,FLAGS.knowledge_path) 47 | id2word_domain = {value: key for key, value in word2id_domain.items()} 48 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 49 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 50 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 51 | 52 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 53 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 54 | 55 | intent_num_classes=len(word2id_intent) 56 | domain_num_classes=len(word2id_domain) 57 | 58 | vocab_size=len(word2id) 59 | slots_num_classes=len(id2word_slotname) 60 | 61 | config = tf.ConfigProto() 62 | config.gpu_options.allow_growth = True 63 | sess = tf.Session(config=config) 64 | FLAGS.batch_size = 1 65 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 66 | 67 | S_Q_len=len(q_list_index) 68 | print("S_Q_len:",S_Q_len) 69 | model = joint_knowledge_domain_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 70 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 71 | sequence_length_batch, slots_num_classes, FLAGS.is_training,domain_num_classes,S_Q_len=S_Q_len) 72 | # initialize Saver 73 | saver = tf.train.Saver() 74 | print('restoring Variables from Checkpoint!') 75 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 76 | 77 | 78 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 79 | jieba.load_userdict(slot_values_file) 80 | 81 | def main(_): 82 | sentence=u'开灯' #u'帮我打开厕所的灯' 83 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 84 | intent,intent_logits, slots,slot_list,similiarity_list_result,domain=predict(sentence) 85 | print(sentence) 86 | print('intent:{},intent_logits:{},domain:{}'.format(intent, intent_logits,domain)) 87 | for slot_name,slot_value in slots.items(): 88 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 89 | for i,element in enumerate(slot_list): 90 | slot_name,slot_value=element 91 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 92 | 93 | #accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 94 | #print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 95 | 96 | predict_interactive() 97 | 98 | 99 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 100 | #1.get validation set 101 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 102 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 103 | #2.loop each data 104 | count_similiarity_right=0 105 | count_classification_right=0 106 | len_validation=len(dict_pair) 107 | 108 | i=0 109 | for sentence,value in dict_pair.items(): 110 | #3.call predict 111 | intent, intent_logits, slots, slot_list, similiarity_list_result,domain = predict(sentence) 112 | y_intent_target=value['intent'] 113 | similiar_intent=similiarity_list_result[0] 114 | if similiar_intent ==y_intent_target: 115 | count_similiarity_right+=1 116 | if intent==y_intent_target: 117 | count_classification_right+=1 118 | if i%10==0: 119 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 120 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 121 | i=i+1 122 | #4.get accuracy 123 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 124 | accuracy_classification = float(count_classification_right) / float(len_validation) 125 | 126 | return accuracy_similiarity,accuracy_classification 127 | 128 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 129 | #1.get validation set 130 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 131 | x_valid, y_intent_valid, y_slots_valid = valid_data 132 | #2.loop each data 133 | count_similiarity_right=0 134 | count_classification_right=0 135 | len_validation=len(x_valid) 136 | for i, x_indices in enumerate(x_valid): 137 | y_intent=y_intent_valid[i] 138 | sentence=get_sentence_from_index(x_indices) 139 | #3.call predict 140 | intent, intent_logits, slots, slot_list, similiarity_list_result,model = predict(sentence) 141 | y_intent_target=id2word_intent[y_intent] 142 | similiar_intent=similiarity_list_result[0] 143 | if similiar_intent ==y_intent_target: 144 | count_similiarity_right+=1 145 | if intent==y_intent_target: 146 | count_classification_right+=1 147 | if i%10==0: 148 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 149 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 150 | #4.get accuracy 151 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 152 | accuracy_classification = float(count_classification_right) / float(len_validation) 153 | 154 | return accuracy_similiarity,accuracy_classification 155 | 156 | def get_sentence_from_index(x_indices): 157 | sentence=[ id2word.get(index,UNK) for index in x_indices] 158 | sentence="".join(sentence) 159 | return sentence 160 | 161 | def predict(sentence,enable_knowledge=1): 162 | """ 163 | :param sentence: a sentence. 164 | :return: intent and slots 165 | """ 166 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 167 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 168 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 169 | #print("predict.y_slots:",y_slots) 170 | qa_list_length=len(q_list_index) 171 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 172 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 173 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 174 | model.dropout_keep_prob:1.0} 175 | logits_intent,logits_slots,similiarity_list,logits_domain = sess.run([model.logits_intent,model.logits_slots,model.similiarity_list,model.logits_domain], feed_dict) #similiarity_list:[1,None] 176 | intent,intent_logits,slots,slot_list,similiarity_list_result,domain=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain) 177 | return intent,intent_logits,slots,slot_list,similiarity_list_result,domain 178 | 179 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 180 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 181 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 182 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 183 | result=[word2id_slotname[O]]*sequence_length 184 | if enable_knowledge=='1' or enable_knowledge==1: 185 | for i,word in enumerate(user_speech_tokenized): 186 | slot_name=knowledge_dict.get(word,None) 187 | #print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 188 | if slot_name is not None: 189 | try: 190 | result[i]=word2id_slotname[slot_name] 191 | except: 192 | pass 193 | return result 194 | 195 | def predict_interactive(): 196 | sys.stdout.write("Please Input Story.>") 197 | sys.stdout.flush() 198 | question = sys.stdin.readline() 199 | enable_knowledge=1 200 | while question: 201 | if question.find("disable_knowledge")>=0: 202 | enable_knowledge=0 203 | print("knowledge disabled") 204 | print("Please Input Story>") 205 | sys.stdout.flush() 206 | question = sys.stdin.readline() 207 | elif question.find("enable_knowledge")>=0: 208 | enable_knowledge=1 209 | #3.read new input 210 | print("knowledge enabled") 211 | print("Please Input Story>") 212 | sys.stdout.flush() 213 | question = sys.stdin.readline() 214 | 215 | #1.predict using quesiton 216 | intent, intent_logits,slots,slot_list,similiarity_list,domain=predict(question,enable_knowledge=enable_knowledge) 217 | #2.print 218 | print('意图:{},置信度:{}'.format(intent, intent_logits)) 219 | print('技能:{}'.format(domain)) 220 | #for i,similiarity in enumerate(similiarity_list): 221 | # print('i:{},similiarity:{}'.format(i, similiarity)) 222 | for slot_name, slot_value in slots.items(): 223 | print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 224 | #for i, element in enumerate(slot_list): 225 | # slot_name, slot_value = element 226 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 227 | #3.read new input 228 | print("Please Input Story>") 229 | sys.stdout.flush() 230 | question = sys.stdin.readline() 231 | 232 | 233 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain,top_number=3): 234 | index_intent= np.argmax(logits_intent[0]) #index of intent 235 | intent_logits=logits_intent[0][index_intent] 236 | #print("intent_logits:",index_intent) 237 | intent=id2word_intent[index_intent] 238 | 239 | index_domain=np.argmax(logits_domain[0]) #index of domain 240 | domain=id2word_domain[index_domain] 241 | 242 | slots=[] 243 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 244 | for i,index in enumerate(indices_slots): 245 | slots.append(id2word_slotname[index]) 246 | slots_dict={} 247 | slot_list=[] 248 | for i,slot in enumerate(slots): 249 | word=id2word[sentence_indices[i]] 250 | #print(i,"slot:",slot,";word:",word) 251 | if slot!=O and word!=PAD and word!=UNK: 252 | slots_dict[slot]=word 253 | slot_list.append((slot,word)) 254 | 255 | #get top answer for the similiarity list. 256 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 257 | similiarity_list_top = similiarity_list_top[::-1] 258 | similiarity_list_result=[] 259 | print('最相关问题') 260 | for k,index in enumerate(similiarity_list_top): 261 | question=q_list[index] 262 | answer=q2a_dict[question] 263 | similiarity_list_result.append(answer) 264 | print('index:{}.问题{}:{}, intent:{}'.format(index,k,question, answer)) 265 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result,domain 266 | 267 | if __name__ == "__main__": 268 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v6_with_domain_knowledge/joint_intent_slots_knowledge_domain_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_domain_model import joint_knowledge_domain_model 14 | from a1_data_util import * 15 | import math 16 | import pickle 17 | 18 | #configuration 19 | FLAGS=tf.app.flags.FLAGS 20 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 21 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 22 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 23 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 24 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 25 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 26 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 27 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 28 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 29 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 30 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 31 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 32 | 33 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 34 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 35 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data _10w.txt","file for data source") #knowledge/sht_20171125.txt 36 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 37 | 38 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 39 | 40 | # create session and load the model from checkpoint 41 | # load vocabulary for intent and slot name 42 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 43 | id2word = {value: key for key, value in word2id.items()} 44 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 45 | id2word_intent = {value: key for key, value in word2id_intent.items()} 46 | word2id_domain= create_or_load_vocabulary_domain(None,FLAGS.knowledge_path) 47 | id2word_domain = {value: key for key, value in word2id_domain.items()} 48 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 49 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 50 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 51 | 52 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 53 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 54 | 55 | intent_num_classes=len(word2id_intent) 56 | domain_num_classes=len(word2id_domain) 57 | 58 | vocab_size=len(word2id) 59 | slots_num_classes=len(id2word_slotname) 60 | 61 | config = tf.ConfigProto() 62 | config.gpu_options.allow_growth = True 63 | sess = tf.Session(config=config) 64 | FLAGS.batch_size = 1 65 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 66 | 67 | S_Q_len=len(q_list_index) 68 | print("S_Q_len:",S_Q_len) 69 | model = joint_knowledge_domain_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 70 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 71 | sequence_length_batch, slots_num_classes, FLAGS.is_training,domain_num_classes,S_Q_len=S_Q_len) 72 | # initialize Saver 73 | saver = tf.train.Saver() 74 | print('restoring Variables from Checkpoint!') 75 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 76 | 77 | 78 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 79 | jieba.load_userdict(slot_values_file) 80 | 81 | def main(_): 82 | sentence=u'开灯' #u'帮我打开厕所的灯' 83 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 84 | intent,intent_logits, slots,slot_list,similiarity_list_result,domain=predict(sentence) 85 | print(sentence) 86 | print('intent:{},intent_logits:{},domain:{}'.format(intent, intent_logits,domain)) 87 | for slot_name,slot_value in slots.items(): 88 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 89 | for i,element in enumerate(slot_list): 90 | slot_name,slot_value=element 91 | print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 92 | 93 | #accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 94 | #print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 95 | 96 | predict_interactive() 97 | 98 | 99 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 100 | #1.get validation set 101 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 102 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 103 | #2.loop each data 104 | count_similiarity_right=0 105 | count_classification_right=0 106 | len_validation=len(dict_pair) 107 | 108 | i=0 109 | for sentence,value in dict_pair.items(): 110 | #3.call predict 111 | intent, intent_logits, slots, slot_list, similiarity_list_result,domain = predict(sentence) 112 | y_intent_target=value['intent'] 113 | similiar_intent=similiarity_list_result[0] 114 | if similiar_intent ==y_intent_target: 115 | count_similiarity_right+=1 116 | if intent==y_intent_target: 117 | count_classification_right+=1 118 | if i%10==0: 119 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 120 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 121 | i=i+1 122 | #4.get accuracy 123 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 124 | accuracy_classification = float(count_classification_right) / float(len_validation) 125 | 126 | return accuracy_similiarity,accuracy_classification 127 | 128 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 129 | #1.get validation set 130 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 131 | x_valid, y_intent_valid, y_slots_valid = valid_data 132 | #2.loop each data 133 | count_similiarity_right=0 134 | count_classification_right=0 135 | len_validation=len(x_valid) 136 | for i, x_indices in enumerate(x_valid): 137 | y_intent=y_intent_valid[i] 138 | sentence=get_sentence_from_index(x_indices) 139 | #3.call predict 140 | intent, intent_logits, slots, slot_list, similiarity_list_result,model = predict(sentence) 141 | y_intent_target=id2word_intent[y_intent] 142 | similiar_intent=similiarity_list_result[0] 143 | if similiar_intent ==y_intent_target: 144 | count_similiarity_right+=1 145 | if intent==y_intent_target: 146 | count_classification_right+=1 147 | if i%10==0: 148 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 149 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 150 | #4.get accuracy 151 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 152 | accuracy_classification = float(count_classification_right) / float(len_validation) 153 | 154 | return accuracy_similiarity,accuracy_classification 155 | 156 | def get_sentence_from_index(x_indices): 157 | sentence=[ id2word.get(index,UNK) for index in x_indices] 158 | sentence="".join(sentence) 159 | return sentence 160 | 161 | def predict(sentence,enable_knowledge=1): 162 | """ 163 | :param sentence: a sentence. 164 | :return: intent and slots 165 | """ 166 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 167 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 168 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 169 | #print("predict.y_slots:",y_slots) 170 | qa_list_length=len(q_list_index) 171 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 172 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 173 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 174 | model.dropout_keep_prob:1.0} 175 | logits_intent,logits_slots,similiarity_list,logits_domain = sess.run([model.logits_intent,model.logits_slots,model.similiarity_list,model.logits_domain], feed_dict) #similiarity_list:[1,None] 176 | print("predict.similiarity_list:",similiarity_list) 177 | intent,intent_logits,slots,slot_list,similiarity_list_result,domain=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain) 178 | return intent,intent_logits,slots,slot_list,similiarity_list_result,domain 179 | 180 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 181 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 182 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 183 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 184 | result=[word2id_slotname[O]]*sequence_length 185 | if enable_knowledge=='1' or enable_knowledge==1: 186 | for i,word in enumerate(user_speech_tokenized): 187 | slot_name=knowledge_dict.get(word,None) 188 | #print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 189 | if slot_name is not None: 190 | try: 191 | result[i]=word2id_slotname[slot_name] 192 | except: 193 | pass 194 | return result 195 | 196 | def predict_interactive(): 197 | sys.stdout.write("Please Input Story.>") 198 | sys.stdout.flush() 199 | question = sys.stdin.readline() 200 | enable_knowledge=1 201 | while question: 202 | if question.find("disable_knowledge")>=0: 203 | enable_knowledge=0 204 | print("knowledge disabled") 205 | print("Please Input Story>") 206 | sys.stdout.flush() 207 | question = sys.stdin.readline() 208 | elif question.find("enable_knowledge")>=0: 209 | enable_knowledge=1 210 | #3.read new input 211 | print("knowledge enabled") 212 | print("Please Input Story>") 213 | sys.stdout.flush() 214 | question = sys.stdin.readline() 215 | 216 | #1.predict using quesiton 217 | intent, intent_logits,slots,slot_list,similiarity_list,domain=predict(question,enable_knowledge=enable_knowledge) 218 | #2.print 219 | print('意图:{},置信度:{}'.format(intent, intent_logits)) 220 | print('技能:{}'.format(domain)) 221 | #for i,similiarity in enumerate(similiarity_list): 222 | # print('i:{},similiarity:{}'.format(i, similiarity)) 223 | for slot_name, slot_value in slots.items(): 224 | print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 225 | #for i, element in enumerate(slot_list): 226 | # slot_name, slot_value = element 227 | # print('slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 228 | #3.read new input 229 | print("Please Input Story>") 230 | sys.stdout.flush() 231 | question = sys.stdin.readline() 232 | 233 | 234 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain,top_number=3): 235 | index_intent= np.argmax(logits_intent[0]) #index of intent 236 | intent_logits=logits_intent[0][index_intent] 237 | #print("intent_logits:",index_intent) 238 | intent=id2word_intent[index_intent] 239 | 240 | index_domain=np.argmax(logits_domain[0]) #index of domain 241 | domain=id2word_domain[index_domain] 242 | 243 | slots=[] 244 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 245 | for i,index in enumerate(indices_slots): 246 | slots.append(id2word_slotname[index]) 247 | slots_dict={} 248 | slot_list=[] 249 | for i,slot in enumerate(slots): 250 | word=id2word[sentence_indices[i]] 251 | #print(i,"slot:",slot,";word:",word) 252 | if slot!=O and word!=PAD and word!=UNK: 253 | slots_dict[slot]=word 254 | slot_list.append((slot,word)) 255 | 256 | #get top answer for the similiarity list. 257 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 258 | similiarity_list_top = similiarity_list_top[::-1] 259 | similiarity_list_result=[] 260 | print('最相关问题') 261 | for k,index in enumerate(similiarity_list_top): 262 | question=q_list[index] 263 | answer=q2a_dict[question] 264 | similiarity_list_result.append(answer) 265 | print('index:{}.问题{}:{}, intent:{}'.format(index,k,question, answer)) 266 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result,domain 267 | 268 | if __name__ == "__main__": 269 | tf.app.run() -------------------------------------------------------------------------------- /joint_model_knowl_v8_slot_condition_intent/joint_intent_slots_knowledge_conditional_predict.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #prediction using model.process--->1.load data. 2.create session. 3.feed data. 4.predict 3 | import sys 4 | reload(sys) 5 | sys.setdefaultencoding('utf8') 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | import tensorflow as tf 11 | import numpy as np 12 | import os 13 | from joint_intent_slots_knowledge_conditional_model import joint_knowledge_conditional_model 14 | 15 | from a1_data_util import * 16 | import math 17 | import pickle 18 | 19 | #configuration 20 | FLAGS=tf.app.flags.FLAGS 21 | tf.app.flags.DEFINE_float("learning_rate",0.001,"learning rate") 22 | tf.app.flags.DEFINE_integer("batch_size", 1, "Batch size for training/evaluating.") #批处理的大小 32-->128 23 | tf.app.flags.DEFINE_integer("decay_steps", 1000, "how many steps before decay learning rate.") #6000批处理的大小 32-->128 24 | tf.app.flags.DEFINE_float("decay_rate", 0.99, "Rate of decay for learning rate.") #0.87一次衰减多少 25 | tf.app.flags.DEFINE_string("ckpt_dir","checkpoint_67800/","checkpoint location for the model") 26 | tf.app.flags.DEFINE_integer("sequence_length",25,"max sentence length") #100 27 | tf.app.flags.DEFINE_integer("embed_size",128,"embedding size") 28 | tf.app.flags.DEFINE_boolean("is_training",False,"is traning.true:tranining,false:testing/inference") 29 | tf.app.flags.DEFINE_integer("num_epochs",10,"number of epochs to run.") 30 | tf.app.flags.DEFINE_integer("validate_step", 1000, "how many step to validate.") #1000做一次检验 31 | tf.app.flags.DEFINE_integer("hidden_size",128,"hidden size") 32 | tf.app.flags.DEFINE_float("l2_lambda", 0.0001, "l2 regularization") 33 | 34 | tf.app.flags.DEFINE_boolean("enable_knowledge",True,"whether to use knwoledge or not.") 35 | tf.app.flags.DEFINE_string("knowledge_path","knowledge_67800","file for data source") #skill3_train_20171114.txt 36 | tf.app.flags.DEFINE_string("data_source","knowledge_67800/training_data_1w.txt","file for data source") #knowledge/sht_20171125.txt training_data_38_50w.txt 37 | tf.app.flags.DEFINE_boolean("test_mode",False,"whether use test mode. if true, only use a small amount of data") 38 | 39 | tf.app.flags.DEFINE_string("validation_file","wzz_training_data_20171211_20w_validation.txt","validation file") 40 | 41 | # create session and load the model from checkpoint 42 | # load vocabulary for intent and slot name 43 | word2id = create_or_load_vocabulary(None,FLAGS.knowledge_path) 44 | id2word = {value: key for key, value in word2id.items()} 45 | word2id_intent = create_or_load_vocabulary_intent(None,FLAGS.knowledge_path) 46 | id2word_intent = {value: key for key, value in word2id_intent.items()} 47 | word2id_domain= create_or_load_vocabulary_domain(None,FLAGS.knowledge_path) 48 | id2word_domain = {value: key for key, value in word2id_domain.items()} 49 | word2id_slotname = create_or_load_vocabulary_slotname_save(None,FLAGS.knowledge_path) 50 | id2word_slotname = {value: key for key, value in word2id_slotname.items()} 51 | knowledge_dict=load_knowledge(FLAGS.knowledge_path) 52 | 53 | basic_pair=FLAGS.knowledge_path+'/raw_data.txt' 54 | q2a_dict,a2q_dict,q_list,q_list_index=process_qa(basic_pair,word2id,FLAGS.sequence_length) 55 | 56 | intent_num_classes=len(word2id_intent) 57 | domain_num_classes=len(word2id_domain) 58 | 59 | vocab_size=len(word2id) 60 | slots_num_classes=len(id2word_slotname) 61 | 62 | config = tf.ConfigProto() 63 | config.gpu_options.allow_growth = True 64 | sess = tf.Session(config=config) 65 | FLAGS.batch_size = 1 66 | sequence_length_batch = [FLAGS.sequence_length] * FLAGS.batch_size 67 | 68 | S_Q_len=len(q_list_index) 69 | print("S_Q_len:",S_Q_len) 70 | model = joint_knowledge_conditional_model(intent_num_classes, FLAGS.learning_rate, FLAGS.decay_steps, FLAGS.decay_rate, 71 | FLAGS.sequence_length, vocab_size, FLAGS.embed_size, FLAGS.hidden_size, 72 | sequence_length_batch, slots_num_classes, FLAGS.is_training,domain_num_classes,S_Q_len=S_Q_len) 73 | # initialize Saver 74 | saver = tf.train.Saver() 75 | print('restoring Variables from Checkpoint!') 76 | saver.restore(sess, tf.train.latest_checkpoint(FLAGS.ckpt_dir)) 77 | 78 | 79 | slot_values_file = FLAGS.knowledge_path+'/slot_values.txt' 80 | jieba.load_userdict(slot_values_file) 81 | 82 | def main(_): 83 | sentence=u'开灯' #u'帮我打开厕所的灯' 84 | #indices=[240, 277, 104, 274, 344, 259, 19, 372, 235, 338, 338, 338, 338, 338, 338] #[283, 180, 362, 277, 99, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338] #u'帮我把客厅的灯打开' 85 | intent,intent_logits, slots,slot_list,similiarity_list_result,domain,domain_score=predict(sentence) 86 | print(sentence) 87 | print('intent:{},intent_logits:{},domain:{}'.format(intent, intent_logits,domain)) 88 | for slot_name,slot_value in slots.items(): 89 | print('slots.slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 90 | for i,element in enumerate(slot_list): 91 | slot_name,slot_value=element 92 | print('slot_list.slot_name:{},slot_value:{}'.format(slot_name, slot_value)) 93 | 94 | #accuracy_similiarity, accuracy_classification=accuarcy_for_similiarity_validation_set() 95 | #print("accuracy_similiarity:",accuracy_similiarity,";accuracy_classification:",accuracy_classification) 96 | 97 | predict_interactive() 98 | 99 | def predict_joint(context_list,query): 100 | """ 101 | :param context_list: a list of string 102 | :param query: a string 103 | :return: 104 | predicted_intent: string 105 | score: a string 106 | slots: a dict 107 | """ 108 | intent, intent_logits, slots, slot_list, similiarity_list_result, domain,domain_logits = predict(query) 109 | return intent,intent_logits,slots 110 | 111 | def predict_with_one_single_question_add_scores(context_list,query): 112 | """ 113 | :param context_list: a list of string 114 | :param query: a string 115 | :return: 116 | predicted_intent: string 117 | score: a string 118 | slots: a dict 119 | """ 120 | intent, intent_logits, slots, slot_list, similiarity_list_result, domain,domain_logits = predict(query) 121 | return intent,intent_logits 122 | 123 | def predict_slots(context_list,current_intent): 124 | """ 125 | :param context_list: a list of string 126 | :param query: a string 127 | :return: 128 | predicted_intent: string 129 | score: a string 130 | slots: a dict 131 | """ 132 | query=context_list[-1] 133 | intent, intent_logits, slots, slot_list, similiarity_list_result, domain,domain_score = predict(query) 134 | return slots 135 | 136 | def accuarcy_for_similiarity_validation_set():#read validation data from outside file, and compute accuarcy for classification model and similiarity model 137 | #1.get validation set 138 | source_file_name=FLAGS.knowledge_path+"/" +FLAGS.validation_file 139 | dict_pair=generate_raw_data(source_file_name, test_mode=False, knowledge_path=FLAGS.knowledge_path, target_file=source_file_name+'_raw_data') 140 | #2.loop each data 141 | count_similiarity_right=0 142 | count_classification_right=0 143 | len_validation=len(dict_pair) 144 | 145 | i=0 146 | for sentence,value in dict_pair.items(): 147 | #3.call predict 148 | intent, intent_logits, slots, slot_list, similiarity_list_result,domain,domain_score = predict(sentence) 149 | y_intent_target=value['intent'] 150 | similiar_intent=similiarity_list_result[0] 151 | if similiar_intent ==y_intent_target: 152 | count_similiarity_right+=1 153 | if intent==y_intent_target: 154 | count_classification_right+=1 155 | if i%10==0: 156 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 157 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 158 | i=i+1 159 | #4.get accuracy 160 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 161 | accuracy_classification = float(count_classification_right) / float(len_validation) 162 | 163 | return accuracy_similiarity,accuracy_classification 164 | 165 | def accuarcy_for_similiarity_validation_setX(): #read cached validation data 166 | #1.get validation set 167 | traing_data, valid_data, test_data, vocab_size, intent_num_classes, slots_num_classes = generate_training_data(FLAGS.data_source,FLAGS.knowledge_path,FLAGS.test_mode,sequence_length=FLAGS.sequence_length) 168 | x_valid, y_intent_valid, y_slots_valid = valid_data 169 | #2.loop each data 170 | count_similiarity_right=0 171 | count_classification_right=0 172 | len_validation=len(x_valid) 173 | for i, x_indices in enumerate(x_valid): 174 | y_intent=y_intent_valid[i] 175 | sentence=get_sentence_from_index(x_indices) 176 | #3.call predict 177 | intent, intent_logits, slots, slot_list, similiarity_list_result,model = predict(sentence) 178 | y_intent_target=id2word_intent[y_intent] 179 | similiar_intent=similiarity_list_result[0] 180 | if similiar_intent ==y_intent_target: 181 | count_similiarity_right+=1 182 | if intent==y_intent_target: 183 | count_classification_right+=1 184 | if i%10==0: 185 | print(i,"count_similiarity_right%:",str(float(count_similiarity_right)/float(i+1)),";count_classification_right%:",str(float(count_classification_right)/float(i+1))) 186 | print('sentence:{},y_intent_target:{},intent_classification:{},intent_similiar:{}'.format(sentence,y_intent_target,intent,similiar_intent)) 187 | #4.get accuracy 188 | accuracy_similiarity=float(count_similiarity_right)/float(len_validation) 189 | accuracy_classification = float(count_classification_right) / float(len_validation) 190 | 191 | return accuracy_similiarity,accuracy_classification 192 | 193 | def get_sentence_from_index(x_indices): 194 | sentence=[ id2word.get(index,UNK) for index in x_indices] 195 | sentence="".join(sentence) 196 | return sentence 197 | 198 | def predict(sentence,enable_knowledge=1): 199 | """ 200 | :param sentence: a sentence. 201 | :return: intent and slots 202 | """ 203 | #print("FLAGS.knowledge_path====>:",FLAGS.knowledge_path) 204 | sentence_indices=index_sentence_with_vocabulary(sentence,word2id,FLAGS.sequence_length,knowledge_path=FLAGS.knowledge_path) 205 | y_slots= get_y_slots_by_knowledge(sentence,FLAGS.sequence_length,enable_knowledge=enable_knowledge,knowledge_path=FLAGS.knowledge_path) 206 | #print("predict.y_slots:",y_slots) 207 | qa_list_length=len(q_list_index) 208 | feed_dict = {model.x: np.reshape(sentence_indices,(1,FLAGS.sequence_length)), 209 | model.y_slots:np.reshape(y_slots,(1,FLAGS.sequence_length)), 210 | model.S_Q:np.reshape(q_list_index,(qa_list_length,FLAGS.sequence_length)), #should be:[self.S_Q_len, self.sentence_len] 211 | model.dropout_keep_prob:1.0} 212 | logits_intent,logits_slots,similiarity_list,logits_domain = sess.run([model.intent_scores,model.logits_slots,model.similiarity_list,model.domain_scores], feed_dict) #similiarity_list:[1,None] 213 | intent,intent_logits,slots,slot_list,similiarity_list_result,domain,domain_logits=get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain) 214 | return intent,intent_logits,slots,slot_list,similiarity_list_result,domain,domain_logits 215 | 216 | def get_y_slots_by_knowledge(sentence,sequence_length,enable_knowledge=1,knowledge_path=None): 217 | """get y_slots using dictt.e.g. dictt={'slots': {'全部范围': '全', '房间': '储藏室', '设备名': '四开开关'}, 'user': '替我把储藏室四开开关全关闭一下', 'intent': '关设备<房间><全部范围><设备名>'}""" 218 | #knowledge_dict=#{'储藏室': '房间', '全': '全部范围', '四开开关': '设备名'} 219 | user_speech_tokenized=tokenize_sentence(sentence,knowledge_path=knowledge_path) #['替', '我', '把', '储藏室', '四开', '开关', '全', '关闭', '一下'] 220 | result=[word2id_slotname[O]]*sequence_length 221 | if enable_knowledge=='1' or enable_knowledge==1: 222 | for i,word in enumerate(user_speech_tokenized): 223 | slot_name=knowledge_dict.get(word,None) 224 | #print('i:{},word_index:{},word:{},slot_name:{}'.format(i,word,id2word.get(word,UNK),slot_name)) 225 | if slot_name is not None: 226 | try: 227 | result[i]=word2id_slotname[slot_name] 228 | except: 229 | pass 230 | return result 231 | 232 | def predict_interactive(): 233 | sys.stdout.write("Please Input Story.>") 234 | sys.stdout.flush() 235 | question = sys.stdin.readline() 236 | enable_knowledge=1 237 | while question: 238 | if question.find("disable_knowledge")>=0: 239 | enable_knowledge=0 240 | print("knowledge disabled") 241 | print("Please Input Story>") 242 | sys.stdout.flush() 243 | question = sys.stdin.readline() 244 | elif question.find("enable_knowledge")>=0: 245 | enable_knowledge=1 246 | #3.read new input 247 | print("knowledge enabled") 248 | print("Please Input Story>") 249 | sys.stdout.flush() 250 | question = sys.stdin.readline() 251 | 252 | #1.predict using quesiton 253 | intent, intent_logits,slots,slot_list,similiarity_list,domain,domain_score=predict(question,enable_knowledge=enable_knowledge) 254 | #2.print 255 | print('技能:{},置信度:{}'.format(domain,domain_score)) 256 | print('意图:{},置信度:{}'.format(intent, intent_logits)) 257 | for slot_name, slot_value in slots.items(): 258 | print('slot_name:{}-->slot_value:{}'.format(slot_name, slot_value)) 259 | score, is_noise=compute_score_noise(domain_score,intent_logits,slots) 260 | print('噪声输入:{},综合分数:{}'.format("是" if is_noise==True else "否",score)) #1 if 5>3 else 0 261 | #3.read new input 262 | print("Please Input Story>") 263 | sys.stdout.flush() 264 | question = sys.stdin.readline() 265 | 266 | def compute_score_noise(domain_score,intent_logits,slots,domain_weight=0.4,intent_weight=0.4,slots_weight=0.2): 267 | """ 268 | compute whether it is a noise or not.今天 269 | :param domain_score: 270 | :param intent_logits: 271 | :param slots: 272 | :return: 273 | """ 274 | score=0.0 275 | is_noise=False 276 | slots_score=min(1.0,float(len(slots))/2.0) 277 | score=domain_weight*domain_score+intent_logits*intent_weight+slots_weight*slots_score 278 | if score>=0.5: 279 | is_noise=False 280 | else: 281 | is_noise=True 282 | return score,is_noise 283 | pass 284 | 285 | def get_result(logits_intent,logits_slots,sentence_indices,similiarity_list,logits_domain,top_number=3): 286 | index_intent= np.argmax(logits_intent[0]) #index of intent 287 | intent_logits=logits_intent[0][index_intent] 288 | #print("intent_logits:",index_intent) 289 | intent=id2word_intent[index_intent] 290 | 291 | index_domain=np.argmax(logits_domain[0]) #index of domain 292 | domain=id2word_domain[index_domain] 293 | domain_score=logits_domain[0][index_domain] 294 | 295 | slots=[] 296 | indices_slots=np.argmax(logits_slots[0],axis=1) #[sequence_length] 297 | for i,index in enumerate(indices_slots): 298 | slots.append(id2word_slotname[index]) 299 | slots_dict={} 300 | slot_list=[] 301 | for i,slot in enumerate(slots): 302 | word=id2word[sentence_indices[i]] 303 | #print(i,"slot:",slot,";word:",word) 304 | if slot!=O and word!=PAD and word!=UNK: 305 | slots_dict[slot]=word 306 | slot_list.append((slot,word)) 307 | 308 | #get top answer for the similiarity list. 309 | similiarity_list_top = np.argsort(similiarity_list)[-top_number:] 310 | similiarity_list_top = similiarity_list_top[::-1] 311 | similiarity_list_result=[] 312 | print('最相关问题') 313 | for k,index in enumerate(similiarity_list_top): 314 | question=q_list[index] 315 | answer=q2a_dict[question] 316 | similiarity_list_result.append(answer) 317 | print('问题{}:{}, action:{}'.format(k,question, answer)) 318 | return intent,intent_logits,slots_dict,slot_list,similiarity_list_result,domain,domain_score 319 | 320 | if __name__ == "__main__": 321 | tf.app.run() --------------------------------------------------------------------------------