流程
NLU模块
- 注册组件
程序启动,首先加载预先定义的组件,注册到registry中。包括如下:
component_classes = [
SpacyNLP, MitieNLP,
SpacyEntityExtractor, MitieEntityExtractor, DucklingExtractor,
CRFEntityExtractor, DucklingHTTPExtractor,
BilstmCRFEntityExtractor,
JiebaPsegExtractor,
EntityEditIntent,
WordVectorsFeaturizer,
BertVectorsFeaturizer,
EmbeddingBertIntentClassifier,
EntitySynonymMapper,
SpacyFeaturizer, MitieFeaturizer, NGramFeaturizer, RegexFeaturizer,
CountVectorsFeaturizer,
MitieTokenizer, SpacyTokenizer, WhitespaceTokenizer, JiebaTokenizer,
SklearnIntentClassifier, MitieIntentClassifier, KeywordIntentClassifier
]
读取Pipeline配置和训练数据
需要一个配置文件,说明,要训练上述哪些组件和顺序,是个训练流程。
language: "zh"
pipeline:
- name: "tokenizer_jieba" #分词
- name: "bert_vectors_featurizer" #分词结果词向量化
ip: '127.0.0.1'
port: 5555
port_out: 5556
show_server_config: True
timeout: 100000
- name: "intent_classifier_tensorflow_embedding_bert" #意图分类
- name: "ner_bilstm_crf" #实体抽取
- name: "jieba_pseg_extractor" #词性抽取补充,比如时间,地点,人名等采用结巴
训练数据,要求定义文本,对应的意图和实体
{
"nlu_data": {
"common_examples": [
{
"text": "帮我查下昨天的邮件",
"intent": "intent_search_mail",
"entities": [
{
"start": 4,
"end": 6,
"value": "昨天",
"entity": "t"
},
{
"start": 7,
"end": 9,
"value": "邮件",
"entity": "item"
}
]
}
]
}
}
3. 开始训练
依据pipeline定义,依次将训练数据解析结构化,输入到pipeline中的组件,每个pipeline中的组件根据自己的责任功能,处理数据,并将结果存在上下文档中,在整个pipeline中流传,每个组件如果有模型生成,最终将持久化到本地目录
Core模块
- 定义训练配置文件(策略配置)和训练数据
policies:
- name: EmbeddingPolicy #RNN
epochs: 100
max_history: 5
- name: FallbackPolicy #fallback
fallback_action_name: 'action_default_fallback'
- name: MemoizationPolicy #内存记忆
max_history: 5
训练数据包括,domain.yml和stories.md
前者定义词槽,意图,动作,后者定义RNN训练的故事,每个意图对应特定的动作模板
- 根据策略配置,生成PolicyEnsemble,就是策略的集合,依次调用各个策略的训练方法训练,最后将模型持久化
- 对话模块交互
- 执行
- RNN原理
首先,根据domain.yml生成的domain,初始化训练特征,包括
self.user_labels = domain.intent_states + domain.entity_states
self.slot_labels = domain.slot_states
self.bot_labels = domain.action_names
self.num_features = (len(self.user_vocab) +
len(self.slot_labels) +
len(self.bot_vocab))
self.user_feature_len = len(self.user_vocab)
self.slot_feature_len = len(self.slot_labels)
其次,从状态追踪tracker当中,获取状态和动作,以及他们的概率置信度,将他们特征化,比如:其中intent代表意图,a,b,c,d代表实体
f = LabelTokenizerSingleStateFeaturizer()
f.user_labels = ["intent_a", "intent_d"]
f.bot_labels = ["c", "b"]
f.user_vocab = {"intent": 2, "a": 0, "d": 1}
f.bot_vocab = {"b": 1, "c": 0}
f.num_features = (len(f.user_vocab) +
len(f.slot_labels) +
len(f.bot_vocab))
encoded = f.encode({"intent_a": 0.5, "prev_b": 0.2, "intent_d": 1.0,
"prev_action_listen": 1.0})
assert (encoded == np.array([0.5, 1.0, 1.5, 0.0, 0.2])).all()
其中“{"intent_a": 0.5, "prev_b": 0.2, "intent_d": 1.0,"prev_action_listen": 1.0}”就是中间的状态和动作的特征表示,最终转化encode为输入RNN的特征数组,即最后的([0.5, 1.0, 1.5, 0.0, 0.2]
总体来说,只要tracker状态中出现的,都会在对应的特征向量上加上对应的概率。整个特征向量组成是,intent特征+slot特征+action特征。特征化后,输入RNN训练。
后续计划
引入深度强化学习和知识图谱,等实现完,再聊