意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功

意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功 意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功我们在开发AI-Agent智能体时通常会使用提示词工程设置场景的带入在实际项目中会有很多场景如果所有提示词都放一起就会超过Token限制则不得不拆分很多场景的提示词。很多场景下用户就必须要选择一个场景进入聊天这样很不智能意图识别用来做前置处理判断用户输入的意图然后帮用户选择场景。意图识别理解用户需求的第一步在问答对话中准确理解用户的意图是构建有效回答的关键。意图识别即判断用户想要什么,相当于为系统定向选择场景帮助系统更精确的选择回复路径。例如当用户询问“查询电影票” 时系统必须确定用户是想查询电影票而不是演唱会票飞机票等。意图识别的难点多意图问题用户的表达可能含有多个含义语义模糊用户输入不规范或语言表达不标准如错别字等。上下文理解不同场景和时间节点下相同的表达可能具有不同的意图。常用的意图识别方法规则模板匹配通过人工设定模板如从[地点]到[地点]的航班将用户输入与模板匹配从而判断意图。虽然精确度高但需大量人力维护不易推广。统计机器学习: 通过提取文本特征如词性标注和词向量化表示借助支持向量机等模型进行分类。适合简单的分类但在复杂意图下效果有限。深度学习: 借助神经网络和预训练模型无需人工设计特征自动完成意图分类。尽管效果好但需要大量标注数据。在RAG系统中意图识别是基础的前置任务它将用户输入映射到最可能的意图为后续的回答生成奠定基础。基于BERT的对话意图运行环境Python 3.8下载代码gitclone https://github.com/Linear95/bert-intent-slot-detector.gitpycharm开发工具导入项目数据准备示例代码里自带了测试数据在data/SMP2019下我们这里直接使用先了解是怎么样使用然后在根据自己的需求去训练数据训练数据以json格式给出每条数据包括三个关键词text表示待检测的文本intent代表文本的类别标签slots是文本中包括的所有槽位以及对应的槽值以字典形式给出。在data/路径下给出了SMP2019数据集作为参考。数据样例如下{text:开微信,domain:app,intent:LAUNCH,slots:{name:微信}}利用data/SMP2019/split_data.py我们可以再将SMP2019的所有数据拆分成一个训练集split_train.json和一个测试集split_test.json运行split_data.py程序 报错UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 35: illegal multibyte sequence增加编码格式encoding‘utf-8’open(train.json, r, encodingutf-8) as f生产意图标签和槽位标签运行extract_labels.py程序 同样报错UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 35: illegal multibyte sequence同样也是要增加编码格式encoding‘utf-8’open(train.json, r, encodingutf-8) as f意图标签以txt格式给出每行一个意图未识别意图以[UNK]标签表示。以SMP2019intent_labels.txt为例[UNK] LAUNCH QUERY ROUTE ...槽位标签与意图标签类似以txt格式给出。包括三个特殊标签 [PAD]表示输入序列中的padding token, [UNK]表示未识别序列标签, [O]表示没有槽位的token标签。对于有含义的槽位标签又分为以’B_开头的槽位开始的标签, 以及以’I_开头的其余槽位标记两种。以SMP2019slot_labels.txt为例[PAD] [UNK] [O] I_ingredient B_ingredient ...根据示例数据训练意图模型可以直接修改train.py代码然后运行if__name____main__:# 训练示例数据生成意图模型parserargparse.ArgumentParser()# environment parametersparser.add_argument(--cuda_devices,typestr,default0,helpset cuda device numbers)parser.add_argument(--no_cuda,actionstore_true,defaultFalse,helpwhether use cuda device for training)# model parametersparser.add_argument(--tokenizer_path,typestr,defaultbert-base-chinese,helppretrained tokenizer loading path)parser.add_argument(--model_path,typestr,defaultbert-base-chinese,helppretrained model loading path)# data parametersparser.add_argument(--train_data_path,typestr,defaultD:\PycharmProjects\\ai\\bert-intent-slot-detector\data\SMP2019\split_train.json,helptraining data path)parser.add_argument(--test_data_path,typestr,defaultD:\PycharmProjects\\ai\\bert-intent-slot-detector\data\SMP2019\split_test.json,helptesting data path)parser.add_argument(--slot_label_path,typestr,defaultD:\PycharmProjects\\ai\\bert-intent-slot-detector\data\SMP2019\slot_labels.txt,helpslot label path)parser.add_argument(--intent_label_path,typestr,defaultD:\PycharmProjects\\ai\\bert-intent-slot-detector\data\SMP2019\intent_labels.txt,helpintent label path)# training parametersparser.add_argument(--save_dir,typestr,defaultD:\PycharmProjects\\ai\\bert-intent-slot-detector\saved_model,helpdirectory to save the model)parser.add_argument(--max_training_steps,typeint,default0,helpmax training step for optimizer, if larger than 0)parser.add_argument(--gradient_accumulation_steps,typeint,default1,helpnumber of updates steps to accumulate before performing a backward() pass.)parser.add_argument(--saving_steps,typeint,default300,helpparameter update step number to save model)parser.add_argument(--logging_steps,typeint,default10,helpparameter update step number to print logging info.)parser.add_argument(--eval_steps,typeint,default10,helpparameter update step number to print logging info.)parser.add_argument(--saving_epochs,typeint,default1,helpparameter update epoch number to save model)parser.add_argument(--batch_size,typeint,default128,helptraining data batch size)parser.add_argument(--train_epochs,typeint,default10,helptraining epoch number)parser.add_argument(--learning_rate,typefloat,default5e-5,helplearning rate)parser.add_argument(--adam_epsilon,typefloat,default1e-8,helpepsilon for Adam optimizer)parser.add_argument(--warmup_steps,typeint,default0,helpwarmup step number)parser.add_argument(--weight_decay,typefloat,default0.0,helpweight decay rate)parser.add_argument(--max_grad_norm,typefloat,default1.0,helpmaximum norm for gradients)argsparser.parse_args()train(args)也可以使用命令行动态传参的方式运行可以使用以下命令进行模型训练这里我们选择在bert-base-chinese预训练模型基础上进行微调python train.py \--cuda_devices0\--tokenizer_pathbert-base-chinese\--model_pathbert-base-chinese\--train_data_path\bert-intent-slot-detector\data\SMP2019\split_train.json\--test_data_path\bert-intent-slot-detector\data\SMP2019\split_test.json\--intent_label_path\bert-intent-slot-detector\data\SMP2019\intent_labels.txt\--slot_label_path\bert-intent-slot-detector\data\SMP2019\slot_labels.txt\--save_dir\bert-intent-slot-detector\saved_model\--batch_size32\--train_epochs5运行成功后会在saved_model生成微调后的模型运行模型 测试意图识别运行detector.py程序,准备识别用户输入的意图if__name____main__:model_pathsaved_model/model/model_epoch2tokenizer_pathsaved_model/tokenizer/intent_pathdata/SMP2019/intent_labels.txtslot_pathdata/SMP2019/slot_labels.txtmodelJointIntentSlotDetector.from_pretrained(model_pathmodel_path,tokenizer_pathtokenizer_path,intent_label_pathintent_path,slot_label_pathslot_path)whileTrue:textinput(input: )print(model.detect(text))下图能正确的识别输入的意图。参考链接https://github.com/Linear95/bert-intent-slot-detector