{
"chainer": {
"in": ["x"],
"in_y": ["y"],
"pipe": [
...
],
"out": ["y_predicted"]
}
}
chainer 是 DeepPavlov 的核心概念,它从异构组件(基于规则/机器学习/深度学习)中建立了一个管道,作为一个整体从管道进行训练和推断。
管道中的每个组件的输入和输出都是名称的数组,例如:
"in": ["tokens", "features"]
"out": ["token_embeddings", "features_embeddings"]
可以把一个组件的输出作为另一个组件的输入:
{
"class": "deeppavlov.models.preprocessors.str_lower:StrLower",
"in": ["x"],
"out": ["x_lower"]
},
{
"name": "nltk_tokenizer",
"in": ["x_lower"],
"out": ["x_tokens"]
}
管道中的每个组件都必须要执行 _call_() 方法,必须有 name 参数或者 class 参数。
- name 参数相当于是这个组件的注册代号
- class 参数的格式:module_name:ClassName
它也可以有其他的参数,也就是 _init_() 方法中的参数,当一个实例初始化的时候,配置中的值可以改写 _init_() 中参数的默认值。
通过id和ref参数,可以重用管道中的组件来处理数据的不同部分: (并不知道有啥用…重用它干啥,为啥不直接再新建一个组件?)
{
"name": "nltk_tokenizer",
"id": "tokenizer",
"in": ["x_lower"],
"out": ["x_tokens"]
},
{
"ref": "tokenizer",
"in": ["y"],
"out": ["y_tokens"]
},
in : 推理过程中输入的数据字段列表,是一个字典,包含text(用户说的话),intents(包含slots:语句里的特征,act:反馈的动作),prev_rep_act之前反馈的动作(循环神经网络需要)
{
'text': 'traditional',
'intents':
[
{
'slots':
[
['food', 'traditional']
],
'act': 'inform'
}
],
'prev_resp_act': 'welcomemsg'
}
in_y : 也是一个字典,包含text(提供服务的人说的话),act(回复的话的类型)
{
'text': 'Hello, welcome to the Cambridge restaurant system. You can ask for restaurants by area, price range or food type. How may I help you?',
'act': 'welcomemsg'
}
????out : 输出的话的每个单词索引
对于训练组件来说,有两个抽象类:Estimator 和 NNModel
- Estimator:适用于任何没有批处理或早期停止的数据,因此在管道初始化时就可以完成。 fit() 方法是必须实现的。一个例子就是 Vocab。
- NNModel:需要更复杂的训练,它只能在监督模式下训练(而 Estimator 可以在监督和非监督两种模式下训练)。这个过程需要好多轮进行周期验证和日志记录。 train_on_batch() 方法是必须实现的。
训练由 train_model_from_config() 函数触发。
Estimator 类型训练需要有 fit_on 参数,里面包含输入参数名的列表。
NNModel 类型训练需要有 in_y 参数,里面包含ground truth回答名字的列表。(在看英文文献的时候,经常会看到 ground truth 这个词汇,翻译的意思是地面实况,放到机器学习里面,再抽象点可以把它理解为真值、真实的有效值或者是标准的答案。)
例如:
[
{
"id": "classes_vocab",
"name": "default_vocab",
"fit_on": ["y"],
"level": "token",
"save_path": "vocabs/classes.dict",
"load_path": "vocabs/classes.dict"
},
{
"in": ["x"],
"in_y": ["y"],
"out": ["y_predicted"],
"name": "intent_model",
"save_path": "classifiers/intent_cnn",
"load_path": "classifiers/intent_cnn",
"classes_vocab": {
"ref": "classes_vocab"
}
}
]
除了 chainer ,训练管道的配置应该还有三个元素: dataset_reader , dataset_iterator 和 train 。如下所示:
{
"dataset_reader": {
"name": ...,
...
}
"dataset_iterator": {
"name": ...,
...
},
"chainer": {
...
}
"train": {
...
}
}
简化版的训练管道包含两个元素: dataset 和 train.
- dataset 元素目前可以用来训练csv和json格式的分类数据。
读取数据,并以特定的格式返回。一个具体的DatasetReader类应该从这个基类继承并注册一个代号:
from deeppavlov.core.common.registry import register
from deeppavlov.core.data.dataset_reader import DatasetReader
@register('dstc2_datasetreader')
class DSTC2DatasetReader(DatasetReader):
DataLearningIterator —— 形成训练所需的数据集(‘train’,’valid ‘,’test’),并将它们分成批处理。一个实例需要继承 deeppavlov.data.data_learning_iterator.DataLearningIterator 这个类,并注册代号。这是个基类,也可以直接使用。
DataFittingIterator —— 对所提供的数据集进行迭代而不需要(‘train’,’valid ‘,’test’)分割,对于不需要训练的 Estimator 很有用。