MindSpore模型精度调优实战(二)精度调试调优思路

转载自 华为云论坛 https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=106624

MindSpore模型精度调优实战(二)

精度调试调优思路

 

MindSpore团队

 

引子:在模型的开发过程中,精度达不到预期常常让人头疼。为了帮助用户解决模型调试调优的问题,我们为MindSpore量身定做了可视化调试调优组件:MindInsight。我们还梳理了针对常见精度问题的调试调优指南,将以“MindSpore模型精度调优实战”系列文章的形式分享出来,希望能帮助用户轻松定位精度问题,快速优化模型精度。

 

本文是系列分享的第二篇,将给出常用的精度调试调优思路。本系列分享假设您的脚本已经能够运行并算出loss值。如果脚本还不能运行,请先参考相关报错提示进行修改。

 

遇到精度问题时,常用调试调优思路如下:

 

1.         检查代码和超参

2.         检查模型结构

3.         检查输入数据

4.         检查loss曲线

5.         检查精度是否达到预期

 

代码是精度问题的重要源头,检查代码重在对脚本和代码做检查,力争在源头发现问题(第2节);模型结构体现了MindSpore对代码的理解,检查模型结构重在检查MindSpore的理解和算法工程师的设计是否一致(第3节);有的问题要到动态的训练过程中才会发现,检查输入数据(第4节)和loss曲线(第5节)正是将代码和动态训练现象结合进行检查;检查精度是否达到预期则是对整体精度调优过程重新审视,并考虑调整超参、解释模型、优化算法等调优手段(第6节)。此外,熟悉模型和工具也是很重要的(第1节)。下面将分别介绍这些思路。

1  精度调优准备

1.1      回顾算法设计,全面熟悉模型

精度调优前,要先对算法设计做回顾,确保算法设计明确。如果参考论文实现模型,则应回顾论文中的全部设计细节和超参选择情况;如果参考其它框架脚本实现模型,则应确保有一个唯一的、精度能够达标的标杆脚本;如果是新开发的算法,也应将重要的设计细节和超参选择明确出来。这些信息是后面检查脚本步骤的重要依据。

 

精度调优前,还要全面熟悉模型。只有熟悉了模型,才能准确理解MindInsight提供的信息,判断是否存在问题,查找问题源头。因此,花时间理解模型算法和结构、理解模型中算子的作用和参数的含义、理解模型所用优化器的特性等模型要素是很重要的。动手分析精度问题细节前,建议先带着问题加深对这些模型要素的了解。

 

1.2      熟悉工具

MindInsight功能丰富,建议用户简单阅读MindInsight教程(https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/visualization_tutorials.html

),了解主要功能。定位精度问题时,建议使能summary训练信息收集功能,在脚本中加入SummaryCollector,并使用训练看板查看训练过程数据,如下图所示。Summary功能的使用指南请见 https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/summary_record.html,训练可视功能的使用指南请见 https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/dashboard.html

MindSpore模型精度调优实战(二)精度调试调优思路

图 3通过MindInsight训练参数详情查看模型超参

 

2 检查模型结构

在模型结构方面,常见的问题有:

算子使用错误(使用的算子不适用于目标场景,如应该使用浮点除,错误地使用了整数除);

权重共享错误(共享了不应共享的权重);

权重冻结错误(冻结了不应冻结的权重);

节点连接错误(应该连接到计算图中的block未连接);

loss函数错误;

优化器算法错误(如果自行实现了优化器)等。

 

建议通过检查模型代码的方式对模型结构进行检查。此外,MindInsight也可以辅助用户对模型结构进行检查。大多数情况下,SummaryCollector会自动记录计算图,通过MindInsight,用户可以方便地对计算图进行查看。模型脚本运行后,建议使用MindInsight计算图可视模块查看模型结构,加深对计算图的理解,确认模型结构符合预期。若有标杆脚本,还可以同标杆脚本对照查看计算图,检查当前脚本和标杆脚本的计算图是否存在重要的差异。

 

MindSpore模型精度调优实战(二)精度调试调优思路

图 4 通过MindInsight训练看板中的计算图模块查看模型结构

 

考虑到模型结构一般都很复杂,期望在这一步就能发现所有的模型结构问题是不现实的。只要通过可视化的模型结构加深对计算图的理解,发现明显的结构问题即可。后面的步骤中,发现了更明确的精度问题现象后,我们还会回到这一步重新检查确认。

 

注1:MindInsight支持查看SummaryCollector记录的计算图和MindSpore context的save_graphs参数导出的pb文件计算图。请参考我们教程中的“计算图可视化”部分了解更多信息(https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/dashboard.html)。

注2:脚本迁移工具可以将PyTorch、TensorFlow框架下编写的模型转换为MindSpore脚本,请访问教程 https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/migrate_3rd_scripts_mindconverter.html 以了解更多信息。

3 检查输入数据

通过检查输入模型的数据,可以结合脚本判断数据处理流水线和数据集是否存在问题。输入数据的常见问题有:

数据缺失值过多;

每个类别中的样本数目不均衡;

数据中存在异常值;

数据标签错误;

训练样本不足;

未对数据进行标准化,输入模型的数据不在正确的范围内;

finetune和pretrain的数据处理方式不同;

训练阶段和推理阶段的数据处理方式不同;

数据处理参数不正确等。

 

MindInsight可以辅助用户对输入数据、数据处理流水线进行检查。大多数情况下,SummaryCollector会自动记录输入模型的数据(数据处理后的数据)和数据处理流水线参数。输入模型的数据会展示在“数据抽样”模块,数据处理流水线参数会展示在“数据图”模块和“数据溯源”模块。

 

通过MindInsight的数据抽样模块,可以检查输入模型的(数据处理流水线处理后的)数据。若数据明显不符合预期(例如数据被裁剪的范围过大,数据旋转的角度过大等),可以判断输入数据出现了一定的问题。

 

通过MindInsight的数据图和数据溯源模块,可以检查数据处理流水线的数据处理过程和具体参数取值,从而发现不合理的数据处理方法。

MindSpore模型精度调优实战(二)精度调试调优思路

图 6通过MindInsight训练看板中的数据图查看数据处理流水线

 

如果有标杆脚本,还可以同标杆脚本对照,检查数据处理流水线输出的数据是否和当前脚本的数据相同。例如,将数据处理流水线输出的数据保存为npy文件,然后使用numpy.allclose()方法对标杆脚本和当前脚本的数据进行对比。如果发现不同,则数据处理阶段可能存在精度问题。

 

若数据处理流水线未发现问题,可以手动检查数据集是否存在分类不均衡、标签匹配错误、缺失值过多、训练样本不足等问题。

4 检查loss曲线

很多精度问题会在网络训练过程中发现,常见的问题或现象有:

权重初始化不合理(例如初始值为0,初始值范围不合理等);

权重中存在过大、过小值;

权重变化过大;

权重冻结不正确;

权重共享不正确;

激活值饱和或过弱(例如Sigmoid的输出接近1,Relu的输出全为0);

梯度爆炸、消失;

训练epoch不足;

算子计算结果存在NAN、INF;

算子计算过程溢出(计算过程中的溢出不一定都是有害的)等。

 

上述这些问题或现象,有的可以通过loss表现出来,有的则难以观察。MindInsight提供了针对性的功能,可以观察上述现象、自动检查问题,帮助您更快定位问题根因。例如:

l  MindInsight的参数分布图模块可以展示模型权重随训练过程的变化趋势;

l  MindInsight的张量可视模块可以展示张量的具体取值,对不同张量进行对比;

l  MindInsight调试器内置了种类丰富,功能强大的检查能力,可以检查权重问题(例如权重不更新、权重更新过大、权重值过大/过小)、梯度问题(例如梯度消失、梯度爆炸)、激活值问题(例如激活值饱和或过弱)、张量全为0、NAN/INF、算子计算过程溢出等问题。调试器使用教程: https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/debugger.html

 

MindSpore模型精度调优实战(二)精度调试调优思路

图 7通过MindInsight训练看板中的标量可视模块查看loss曲线

大多数情况下,SummaryCollector会自动记录模型的loss曲线,可以通过MindInsight的标量可视模块查看。loss曲线能够反映网络训练的动态趋势,通过观察loss曲线,可以得到模型是否收敛、是否过拟合等信息。

 

MindSpore模型精度调优实战(二)精度调试调优思路

图 8通过MindInsight参数分布图可以查看训练过程中的权重变化情况

大多数情况下,SummaryCollector会自动记录模型参数变化情况(默认记录5个参数),可以通过MindInsight的参数分布图模块查看。如果想要记录更多参数的参数分布图,请参考SummaryCollector的histogram_regular参数(https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.train.html#mindspore.train.callback.SummaryCollector),或参考HistogramSummary算子(https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/summary_record.html#summarysummarycollector)。

 

MindSpore模型精度调优实战(二)精度调试调优思路

图 9通过MindInsight训练看板中的张量可视模块查看特定张量的具体取值

张量不会被自动记录,如果想要通过MindInsight查看张量的具体取值,请使用TensorSummary算子 (https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/summary_record.html#summarysummarycollector)。

 

下面结合loss曲线的常见现象介绍使用MindInsight进行精度问题定位的思路。

4.1 loss跑飞

loss跑飞是指loss中出现了NAN、+/-INF或者特别大的值。loss跑飞一般意味着算法设计或实现存在问题。定位思路如下:

  1. 回顾脚本、模型结构和数据,

    1. 检查超参是否有不合理的特别大/特别小的取值,

    2. 检查模型结构是否实现正确,特别是检查loss函数是否实现正确,

    3. 检查输入数据中是否有缺失值、是否有特别大/特别小的取值。

  2. 观察训练看板中的参数分布图,检查参数更新是否有明显的异常。若发现参数更新异常,可以结合调试器定位参数更新异常的原因。

  3. 使用调试器模块对训练现场进行检查。

  4. 若loss值出现NAN、+/-INF,可使用“检查张量溢出”条件添加全局监测点,定位首先出现NAN、+/-INF的算子节点,检查算子的输入数据是否会导致计算异常(例如除零)。若是算子输入数据的问题,则可以针对性地加入小数值epsilon避免计算异常。

  5. 若loss值出现特别大的值,可使用“检查过大张量”条件添加全局监测点,定位首先出现大值的算子节点,检查算子的输入数据是否会导致计算异常。若输入数据本身存在异常,则可以继续向上追踪产生该输入数据的算子,直到定位出具体原因。

  6. 若怀疑参数更新、梯度等方面存在异常,可使用“检查权重变化过大”、“检查梯度消失”、“检查梯度过大”等条件设置监测点,定位到异常的权重或梯度,然后结合张量检查视图,逐层向上对可疑的正向算子、反向算子、优化器算子等进行检查。

 

4.2 loss收敛慢

loss收敛慢是指loss震荡、收敛速度慢,经过很长时间才能达到预期值,或者最终也无法收敛到预期值。相较于loss跑飞,loss收敛慢的数值特征不明显,更难定位。定位思路如下:

  1. 回顾脚本、模型结构和数据,

    1. 检查超参是否有不合理的特别大/特别小的取值,特别是检查学习率是否设置过小或过大,学习率设置过小会导致收敛速度慢,学习率设置过大会导致loss震荡、不下降;

    2. 检查模型结构是否实现正确,特别是检查loss函数、优化器是否实现正确;

    3. 检查输入数据的范围是否正常,特别是输入数据的值是否过小

  2. 观察训练看板中的参数分布图,检查参数更新是否有明显的异常。若发现参数更新异常,可以结合调试器定位参数更新异常的原因。

  3. 使用调试器模块对训练现场进程检查。

  4. 可使用“检查权重变化过小”、“检查未变化权重”条件对可训练(未固定)的权重进行监测,检查权重是否变化过小。若发现权重变化过小,可进一步检查学习率取值是否过小、优化器算法是否正确实现、梯度是否消失,并做针对性的修复。

  5. 可使用“检查梯度消失”条件对梯度进行监测,检查是否存在梯度消失的现象。若发现梯度消失,可进一步向上检查导致梯度消失的原因。例如,可以通过“检查激活值范围”条件检查是否出现了激活值饱和、Relu输出为0等问题。

 

4.3 其它loss现象

若训练集上loss为0,一般说明模型出现了过拟合,请尝试增大训练集大小。

5 检查精度是否达到预期

MindInsight可以为用户记录每次训练的精度结果。在model.train和model.eval中使用同一个SummaryCollector实例时,会自动记录模型评估(metrics)信息。训练结束后,可以通过MindInsight的模型溯源模块检查训练结果精度是否达标。

MindSpore模型精度调优实战(二)精度调试调优思路

<p style="margin->图 10通过MindInsight溯源分析功能查看模型评估信息

 

若模型的loss值、metric值未达到预期,可以参考以下思路进行定位和优化:

  • 回顾代码、模型结构、输入数据和loss曲线,

    • 检查超参是否有不合理的值

    • 检查模型结构是否实现正确

    • 检查输入数据是否正确

  • 检查loss曲线的收敛结果和收敛趋势是否存在异常

  • 尝试使用MindInsight溯源分析功能优化超参。溯源分析页面会对超参的重要性进行分析,用户应优先考虑调整重要性高的超参,从散点图中可以观察出超参和优化目标的关系,从而针对性地调整超参取值。

MindSpore模型精度调优实战(二)精度调试调优思路

图 11通过MindInsight溯源分析查看参数重要性

MindSpore模型精度调优实战(二)精度调试调优思路

图 12通过MindInsight溯源分析以散点图形式查看参数和优化目标的关系

 

6      小结

由于相同的现象存在多个可能原因,精度问题的定位非常依赖专家经验。希望上述定位方法和功能能够起到良好的引导的作用,帮助你不断积累成功经验,成为精度调优大师。

 

7 欢迎关注我们

MindSpore官网: https://www.mindspore.cn/

MindSpore代码仓库: https://gitee.com/mindspore/mindspore

MindInsight代码仓库: https://gitee.com/mindspore/mindinsight

MindInsight使用教程: https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/visualization_tutorials.html

 

 

上一篇:单精度和半精度混合训练


下一篇:MindSpore模型精度调优实践