如何将bert应用在rasa-nlu-gao
将BERT
应用到rasa-nlu-gao,其实在rasa对话系统踩坑记(四)的开头有简单提到过。当时觉得没什么,所以就略过了。但最近肖大神的bert-as-service项目改动的比较大,致使有朋友反馈现在BERT
的component跑不了了,所以今天将bert-as-service
更新到了最新的版本和最新的方法,这儿做个简单的总结。具体的demo可以参照rasa_chatbot_cn。
BERT
BERT这个深水炸弹一经引爆,在nlp领域反响剧烈。几乎席卷了nlp的所有领域。如果用一句话形容BERT的出现,一切过往,皆为序章。
那当然作为rasa-nlu的资深玩家,当然不能错过,所以早在一个月前我就加上去了。然后最近根据bert-as-service这个项目的更新做了调整。
bert-as-service
想要将bert-as-service用起来,首先需要将service和client下载下来。
pip install bert-serving-server==1.6.0 # server
pip install bert-serving-client==1.6.0 # client, independent of `bert-serving-server`
然后需要下载一个Pre-trained BERT Model,再启动一个BERT服务
bert-serving-start -model_dir /tmp/chinese_L-12_H-768_A-12/ -num_worker=4
对应的bert-serving-start的参数参见bert-as-service
rasa_nlu_bert_finetune(增加@2019-01-11)
之前在rasa-nlu-gao中使用bert训练,是用的google开源的中文model(chinese_L-12_H-768_A-12),而并没有将finetune加上去。最近将这一功能加了上去,代码传送rasa-bert-finetune。主要是在run_classifier.py
代码里面加了RasaJsonProcessor
function,代码如下:
class RasaJsonProcessor(DataProcessor):
def __init__(self):
self.labels = set()
def get_train_examples(self, data_dir):
file_path = os.path.join(data_dir, "rasa_dataset_training.json")
return self._create_examples(self._read_json(file_path), "train")
def get_dev_examples(self, data_dir):
file_path = os.path.join(data_dir, "rasa_dataset_testing.json")
return self._create_examples(self._read_json(file_path), "dev")
def get_labels(self):
return list(self.labels)
def _create_examples(self, lines, set_type):
examples = []
data = lines['rasa_nlu_data']['common_examples']
for (i, line) in enumerate(data):
guid = "%s-%s" % (set_type, i)
text_a = tokenization.convert_to_unicode(line['text'])
label = tokenization.convert_to_unicode(line['intent'])
self.labels.add(label)
examples.append(InputExample(guid=guid, text_a=text_a, label=label))
return examples
训练finetune前先要准备好rasa json的训练数据,train为rasa_dataset_training.json,dev为rasa_dataset_testing.json,这只是命名的问题。训练完成之后,需要在bert-as-server命令行中加上tuned_model_dir
这个参数即可,比如:
bert-serving-start -model_dir ./chinese_L-12_H-768_A-12/ -num_worker=4 -tuned_model_dir ./rasa_model_output/
这样的话,之后使用bert_vectors_featurizer
调用就会是finetune之后的model了。就是如此简单 :)
bert_vectors_featurizer
我在rasa-nlu-gao
中增加了bert_vectors_featurizer组件,并已发布,请pip install rasa-nlu-gao
至最新版本。如名字所示,bert_vectors_featurizer组件只是提供word embedding featurizer.后面可以接其他的分类器,这里用的是intent_classifier_tensorflow_embedding组件,当然你也可以自己加个全连接和softmax分类。具体的配置如下:
language: "zh"
pipeline:
- name: "tokenizer_jieba"
- name: "bert_vectors_featurizer"
ip: '172.16.10.46'
port: 5555
port_out: 5556
show_server_config: True
timeout: 10000
- name: "intent_classifier_tensorflow_embedding"
- name: "ner_crf"
- name: "jieba_pseg_extractor"
- ip: 指的是service的ip地址
- port: 指的是从客户端传到服务端数据的端口,需要和服务端设置的一致
- prot_out: 指的是将结果从服务端传到客户端的端口,需要和服务端一致
- show_server_config: 是否在第一次连接时候展示服务端的config信息
- timeout: 设置客户端接收服务端操作的过期时间
intent_classifier_tensorflow_embedding_bert
bert_vectors_featurizer
说的是将bert应用在词嵌入方面,然后在意图分类这块可以接rasa-nlu官网的intent_classifier_tensorflow_embedding
组件。当然这里的intent_classifier_tensorflow_embedding_bert
组件是同组的飞龙同学加的。该组件是将bert_vectors_featurizer
之后的输出向量做了全连接+softmax。具体的配置可以参考如下:
language: "zh"
pipeline:
- name: "tokenizer_jieba"
- name: "bert_vectors_featurizer"
ip: '172.16.10.46'
port: 6555
port_out: 6556
show_server_config: True
timeout: 10000
- name: "intent_classifier_tensorflow_embedding_bert"
- name: "ner_crf"
- name: "jieba_pseg_extractor"
除了这两个模型外,还可以自定义其他的复杂点的分类模型,也欢迎大家fork该项目,并给我们提pull request,一起完善该模型。当然也欢迎大家star该项目。
大概就这么多,其实用法很简单。原创文章,转载请说明出处