rasa对话系统踩坑记(八)

如何将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该项目。

大概就这么多,其实用法很简单。原创文章,转载请说明出处

你可能感兴趣的:(rasa对话系统踩坑记(八))