Parakeet/docs_cn/experiment_guide_cn.md

4.2 KiB
Raw Blame History

如何准备自己的实验

对于一般的深度学习实验,有几个部分需要处理。

  1. 按照模型的需要对数据进行预处理,并且按批次迭代数据集;
  2. 定义模型以及优化器等组件;
  3. 写出训练过程(一般包括 forward/backward 计算参数更新log 记录,可视化,定期评估等步骤);
  4. 配置并运行实验。

数据处理

对于数据处理,parakeet.data 采用了 paddlepaddle 常用的 Dataset -> DataLoader 的流程。数据处理流程的概览如下:

Dataset --(transform)--> Dataset  --+
                         sampler  --+
                         batch_fn --+-> DataLoader

其中 transform 代表的是对样例的预处理。可以使用 parakeet.data 中的 TransformDataset 来从一个 Dataset 构建另一个 Dataset.

得到想要的 Dataset 之后,提供 sampler 和 batch function, 即可据此构建 DataLoader. DataLoader 产生的结果可以直接用作模型的输入。

详细的使用方式参见 data_cn.

模型

为了对模型的可复用行和功能做较好的平衡,我们把模型按照其特征分为几种。

对于较为常用,可以作为其他更大的模型的部分的模块,我们尽可能将其实现得足够简单和通用,因为它们会被复用。对于含有可训练参数的模块,一般实现为 paddle.nn.Layer 的子类,但它们不是直接面向一个任务,因此不会带上处理未加工的输入和输出的功能。对于不含有可训练参数的模块,可以直接实现为一个函数,其输入输出都是 paddle.Tensor 或其集合。

针对一个特定任务的开箱模型,一般实现为 paddle.nn.Layer 的子类,是一个任务的核心计算单元。为了方便地处理输入和输出,一般还可以为它添加处理未加工的输入输出的功能。比如对于 NLP 任务来说,尽管神经网络接受的输出是文本的 id, 但是为了使模型能够处理未加工的输入,文本预处理的功能,以及文本转 id 的字典,也都应该视作模型的一部分。

当一个模型足够复杂,对其进行模块化切分是更好的选择,尽管拆分出来的小模块的功能也不一定非常通用,可能只是用于某个模型,但是当作么做有利于代码的清晰简洁时,仍然推荐这么做。

在 parakeet 的目录结构中,复用性较高的模块被放在 parakeet.modules, 但是针对特定任务的模型则放在 parakeet.models.

当开发新的模型的时候,开发这需要考虑拆分模块的可行性,以及模块的通用程度,把它们分置于合适的目录。

配置实验

我们使用 yacs 和 argparse 分别处理配置文件解析和命令行参数解析。关于配置的推荐方式,参考 实验配置.

训练流程

训练流程一般就是多次训练一个循环体。典型的循环体包含如下的过程:

  1. 迭代数据集;
  2. 处理批次数据;
  3. 神经网络的 forward/backward 计算;
  4. 参数更新;
  5. 符合一定条件时,在验证数据集上评估模型;
  6. 写日志,可视化,以及在某些情况下保存必要的中间结果;
  7. 保存模型和优化器的状态。

数据处理 包含了数据集以及 batch_function 的定义, 模型和优化器包含了模型的 forward/backward 计算的定义。而在模型和数据都准备好了,我们需要把这些组织起来,完成实验代码。

训练流程的组装,可以参考 实验流程.

实验模板

实验代码一般以如下的方式组织:

├── README.md        (实验的帮助信息)
├── config.py        (默认配置)
├── preprocess.py    (数据预处理脚本)
├── data.py          (Dataset, batch_function 等的定义)
├── synthesis.py     (用于生成的代码)
├── train.py         (用于训练的代码)
└── utils.py         (其他必要的辅助函数)

在这个软件源中包含了几个例子,可以在 Parakeet/examples 中查看。这些实验被作为样例提供给用户,可以直接运行。同时也欢迎用户添加新的模型和实验并为 Parakeet 贡献代码。