---
title: 稀疏流程
description: "本节介绍手工稀疏特性支持的稀疏层，接口调用流程和调用示例。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/devaids/amct/atlasamct_16_0186.html
sourcePath: /source/zh/canncommercial/900/devaids/amct/atlasamct_16_0186.html
indexId: a3382cdf66d45366f24f90b72204f87eb1a0e19a82624381590b3ba8ff0c23bf65
---
# 稀疏流程

本节介绍手工稀疏特性支持的稀疏层，接口调用流程和调用示例。

AMCT目前主要支持基于重训练的通道稀疏模型压缩特性，稀疏示例请参见样例列表>TensorFlow>通道稀疏（手工稀疏）。支持通道稀疏的层以及约束如下：


**表1 通道稀疏支持的层以及约束**

| 支持的层类型 | 约束 |
| --- | --- |
| MatMul | transpose\_a=False、transpose\_b=True/False、adjoint\_a=False、adjoint\_b=True/False 权重数据类型为float32，float64 |
| Conv2D | 权重数据类型为float32，float64 weight的输入来源不含有placeholder等可动态变化的节点，且weight的节点类型只能是const |


#### 接口调用流程

通道稀疏功能接口调用流程如下图所示，如下流程中的训练环境借助TensorFlow框架的CPU/GPU环境，在该开源框架的推理脚本基础上，调用AMCT API完成模型压缩，压缩后的部署模型需要使用ATC工具转换成适配AI处理器的离线模型后，然后才能在AI处理器上实现推理：

图1 通道稀疏接口调用流程


蓝色部分为用户实现，灰色部分为用户调用AMCT提供的API实现，用户在TensorFlow原始网络推理的代码中导入库，并在特定的位置调用相应API，即可实现稀疏功能。

简要流程如下：1. 用户构造训练模式的图结构，调用  create_prune_retrain_model
接口，根据稀疏配置文件对训练的图进行稀疏前的图结构修改：在图结构中插入mask稀疏算子。
2. 训练模型，将训练后的参数保存为checkpoint文件。
3. 用户构造推理模式的图结构，调用稀疏图修改接口  create_prune_retrain_model
，同时根据配置文件对推理的图进行稀疏前的图结构修改：在图结构中插入mask稀疏算子；同时生成记录稀疏信息的record文件。
4. 创建会话，恢复训练参数，并将推理图固化为pb模型。
5. 调用稀疏图保存接口  save_prune_retrain_model
，根据record文件以及固化模型，导出通道裁剪后的pb推理模型，同时删除插入的mask稀疏算子。


#### 调用示例

1. 如下示例标有“由用户补充处理”的步骤，需要用户根据自己的模型和数据集进行补充处理，示例中仅为示例代码。
2. 调用AMCT的部分，函数入参可以根据实际情况进行调整。量化感知训练基于用户的训练过程，请确保已经有基于TensorFlow环境进行训练的脚本，并且训练后的精度正常。


1. 导入AMCT包，设置日志级别。
  1 2 import amct_tensorflow as amct amct.set_logging_level(print_level='info', save_level='info')

2. （可选，由用户补充处理）创建图并读取训练好的参数，在TensorFlow环境下推理，验证环境、推理脚本是否正常。
  推荐执行该步骤，以确保原始模型可以完成推理且精度正常；执行该步骤时，可以使用部分测试集，减少运行时间。

  1 user_test_evaluate_model(evaluate_model, test_data)

3. （由用户补充处理）创建训练图。
  1 train_graph = user_load_train_graph()

4. 调用AMCT，执行带稀疏算子的训练流程。

  a. 在训练图中插入稀疏算子。
    用户基于构造的训练模式的图结构（BN的is_training参数为True） ，调用create_prune_retrain_model接口（对应图1中的序号1），根据稀疏配置文件（对应图1中的序号2）对训练的图进行稀疏前的图结构修改。create_prune_retrain_model接口会在图结构中插入mask算子，达到推理时伪稀疏的效果。稀疏配置文件需要参见量化感知训练简易配置文件自行构造。

    1 2 3 4 5 6 record_file = './tmp/record.txt' simple_cfg = './retrain.cfg' amct.create_prune_retrain_model(graph=train_graph, outputs=user_model_outputs, record_file=record_file, config_defination=simple_cfg)

    由于tf.graph不具有直接删减通道的能力，修改网络中某一个算子的规格，TensorFlow会校验图结构的正确性，导致无法删减通道。因此TensorFlow通过增加mask算子，训练时通过mask算子来屏蔽掉被稀疏通道对整网训练的影响。

  b. （由用户补充处理）使用修改后的图，创建反向梯度，在训练集上做训练。

    1. 使用修改后的图，创建反向梯度。
      调用自适应学习率优化器（比如RMSPropOptimizer）建立反向梯度图（该步骤需要在1后执行）。 1 2 3 optimizer = tf.compat.v1.train.RMSPropOptimizer( ARGS.learning_rate, momentum=ARGS.momentum) train_op = optimizer.minimize(loss)

    2. 训练模型。
      创建会话，进行模型的训练，将训练后的参数保存为checkpoint文件，并得到稀疏算子的结果（对应图1中的序号3，4）。 1 2 3 4 5 with tf.Session() as sess: sess.run(tf.compat.v1.global_variables_initializer()) sess.run(outputs) #将训练后的参数保存为checkpoint文件 saver_save.save(sess, retrain_ckpt, global_step=0)

5. （由用户补充处理）创建推理图。
  1 test_graph = user_load_test_graph()

6. 调用AMCT，实现通道稀疏。

  a. 先在推理图中插入稀疏算子。
    用户基于构建的推理模式的图结构（BN的is_training参数为False），调用稀疏图修改接口create_prune_retrain_model，同时根据配置文件对推理的图进行稀疏前的图结构修改（对应图1中的序号5），同时生成记录稀疏信息的record文件（对应图1中的序号6）。 1 2 3 4 5 6 record_file = './tmp/record.txt' simple_cfg = './retrain.cfg' amct.create_prune_retrain_model(graph=test_graph, outputs=user_model_outputs, record_file=record_file, config_defination=simple_cfg)

  b. 恢复    4
中训练得到的checkpoint权重并固化为pb模型。
    创建会话，恢复训练参数，并将推理图固化为pb模型（对应图1中的序号7， 8）。 1 2 3 4 5 6 7 8 9 10 11 variables_to_restore = tf.compat.v1.global_variables() saver_restore = tf.compat.v1.train.Saver(variables_to_restore) with tf.Session() as sess: sess.run(tf.compat.v1.global_variables_initializer()) #恢复训练参数 saver_restore.restore(sess, retrain_ckpt) #固化pb模型 constant_graph = tf.compat.v1.graph_util.convert_variables_to_constants( sess, eval_graph.as_graph_def(), [output.name[:-2] for output in outputs]) with tf.io.gfile.GFile(masked_pb_path, 'wb') as f: f.write(constant_graph.SerializeToString())

  c. 保存模型，删除插入的mask稀疏算子，并实现通道稀疏。
    根据record文件以及固化模型，导出通道裁剪后的pb推理模型（对应图1中的序号6，9）。 1 2 3 4 5 pruned_model_path = './result/user_model' amct.save_prune_retrain_model(pb_model=masked_pb_path, outputs=user_model_outputs, record_file=record_file, save_path=pruned_model_path)

7. （可选，由用户补充处理）使用稀疏后模型user_model_pruned.pb和测试集，在TensorFlow的环境下推理，测试稀疏后的仿真模型精度。
  使用稀疏后仿真模型精度与2中的原始精度做对比，可以观察稀疏对精度的影响。 1 2 pruned_model = './results/user_model_pruned.pb' user_do_inference(pruned_model, test_data)
