Parakeet/docs/experiment_guide_cn.md

5.0 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.

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

训练流程

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

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

数据处理 一节包含了 1 和 2, 模型和优化器包含了 3 和 4. 那么 5,6,7 是训练流程主要要完成的事情。为了使训练循环体简洁清晰,推荐将模型的保存和加载,模型评估,写日志以及可视化等功能都实现成函数,尽管很多情况下,它们可能需要访问很多局部变量。我们也正在考虑使用一个 Experiment 或者 Trainer 类来规范化这些训练循环体的写法。这样可以把一些需要被许多函数访问的变量作为类内的变量,可以使代码简洁而不至于引入太多的全局变量。

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

├── configs/         (实验配置)
├── data.py          (Dataset, DataLoader 等的定义)
├── README.md        (实验的帮助信息)
├── synthesis.py     (用于生成的代码)
├── train.py         (用于训练的代码)
└── utils.py         (其他必要的辅助函数)

配置实验

深度学习实验常常有很多选项可配置。这些配置大概可以被分为几类:

  1. 数据源以及数据处理方式配置;
  2. 实验结果保存路径配置;
  3. 数据预处理方式配置;
  4. 模型结构和超参数配置;
  5. 训练过程配置。

这些配置之间也可能存在某些重叠项,比如数据预处理部分的配置可能就和模型配置有关。比如说 mel 频谱的维数。

有部分配置是经常会发生改变的,比如数据源以及保存实验结果的路径,或者加载的 checkpoint 的路径等。对于这些配置,更好的做法是把它们实现为命令行参数。其余的不经常发生变动的参数,推荐将其写在配置文件中,我们推荐使用 yaml 作为配置文件,因为它允许添加注释,并且更加人类可读。

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