配置文件
chainer 配置
{
"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 : 输出的话的每个单词索引
Training – 训练
对于训练组件来说,有两个抽象类:Estimator 和 NNModel
- Estimator:适用于任何没有批处理或早期停止的数据,因此在管道初始化时就可以完成。 fit() 方法是必须实现的。一个例子就是 Vocab。
- NNModel:需要更复杂的训练,它只能在监督模式下训练(而 Estimator 可以在监督和非监督两种模式下训练)。这个过程需要好多轮进行周期验证和日志记录。 train_on_batch() 方法是必须实现的。
训练由 train_model_from_config() 函数触发。
train 配置
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格式的分类数据。
训练参数
- epochs —— 训练NNModel的最大轮数,默认是-1(代表无穷)
- batch_size —— 批量大小
- metrics —— 用于评估模型的注册的指标列表,列表中的第一个指标用于早期停止
注:早期停止(Early Stop)神经网络中具体的做法如下:
1. 首先将训练数据划分为训练集和验证集(划分比例为2:1);
2. 在训练集上进行训练,并且在验证集上获取测试结果(比如每隔5个epoch测试一下),随着epoch的增加,如果在验证集上发现测试误差上升,则停止训练;
3. 将停止之后的权重作为网络的最终参数。
Early Stop能够防止过拟合。 - metric_optimization —— 最优化度量,即最大化(maximize )或最小化(minimize )度量,默认为最大化(maximize )
- validation_patience —— 早期停止前,在一行中有多少次验证指标没有改进,默认值为5
- val_every_n_epochs —— 验证管道的频率,默认为-1(从不)
- log_every_n_batches,log_every_n_epochs —— 计算训练数据指标的频率,默认为-1(从不)
- validate_best,test_best —— 在有效和测试数据上用于推断保存的最佳模型的标志,默认为true
- tensorboard_log_dir —— 在训练期间编写日志度量的路径。使用tensorboard可以实现可视化度量图。
DatasetReader
读取数据,并以特定的格式返回。一个具体的DatasetReader类应该从这个基类继承并注册一个代号:
from deeppavlov.core.common.registry import register
from deeppavlov.core.data.dataset_reader import DatasetReader
@register('dstc2_datasetreader')
class DSTC2DatasetReader(DatasetReader):
DataLearningIterator & DataFittingIterator
DataLearningIterator —— 形成训练所需的数据集(‘train’,’valid ‘,’test’),并将它们分成批处理。一个实例需要继承 deeppavlov.data.data_learning_iterator.DataLearningIterator 这个类,并注册代号。这是个基类,也可以直接使用。
DataFittingIterator —— 对所提供的数据集进行迭代而不需要(‘train’,’valid ‘,’test’)分割,对于不需要训练的 Estimator 很有用。