减少卷积网络的 Jedi 技术——剪枝

减少卷积网络的 Jedi 技术——剪枝

再次摆在您面前的是检测物体的任务。 优先考虑的是操作速度和可接受的精度。 您采用 YOLOv3 架构并进一步训练它。 准确度(mAP75)大于0.95。 但运行率仍然较低。 废话。

今天我们将绕过量化。 在切口下我们会看到 模型剪枝 - 修剪网络的冗余部分以加速推理而不损失准确性。 切割地点、切割量以及切割方式一目了然。 让我们弄清楚如何手动执行此操作以及在哪里可以自动执行此操作。 最后有一个关于 keras 的存储库。

介绍

在我之前的工作地点彼尔姆的Macroscop,我养成了一个习惯——始终监控算法的执行时间。 并始终通过充分性过滤器检查网络运行时。 通常最先进的生产不会通过这个过滤器,这导致我进行修剪。

修剪是一个古老的话题,在 斯坦福大学讲座 2017年。 主要思想是通过删除各种节点来减少训练网络的大小而不损失准确性。 听起来很酷,但我很少听说它的用途。 可能是没有足够的实现,没有俄语文章,或者只是每个人都认为它是修剪技术并保持沉默。
但让我们把它拆开

生物学一瞥

我喜欢深度学习研究来自生物学的想法。 它们就像进化一样,是可以信任的(你知道 ReLU 与 大脑神经元激活的功能?)

模型剪枝过程也接近生物学。 网络的反应可以与大脑的可塑性进行比较。 书中有几个有趣的例子。 诺曼·道伊奇:

  1. 一名出生时只有一半的女性的大脑已经重新编程,以执行缺失的一半的功能。
  2. 那家伙射掉了他大脑中负责视觉的部分。 随着时间的推移,大脑的其他部分接管了这些功能。 (我们不想重复)

同样,您可以从模型中删除一些弱卷积。 作为最后的手段,剩余的捆绑包将有助于替换切割的捆绑包。

您喜欢迁移学习还是从头开始学习?

选项一。 您在 Yolov3 上使用迁移学习。 视网膜、Mask-RCNN 或 U-Net。 但大多数时候我们不需要像 COCO 中那样识别 80 个对象类。 在我的实践中,一切都仅限于1-2年级。 人们可能会认为 80 个类的架构在这里是多余的。 这表明架构需要变得更小。 此外,我想在不丢失现有预训练权重的情况下做到这一点。

选项二。 也许你拥有大量的数据和计算资源,或者只是需要一个超级定制的架构。 没关系。 但你是从头开始学习网络。 通常的过程是查看数据结构,选择功率过大的架构,然后从再训练中退出。 我看到 0.6 人辍学,卡尔。

在这两种情况下,都可以减少网络。 有动力。 现在我们就来了解一下什么是包皮环切修剪

通用算法

我们决定删除这些捆绑包。 看起来很简单:

减少卷积网络的 Jedi 技术——剪枝

删除任何卷积会给网络带来压力,这通常会导致错误增加。 一方面,错误的增加表明我们删除卷积的正确程度(例如,大幅增加表明我们做错了什么)。 但小幅增加是完全可以接受的,并且通常可以通过随后使用小 LR 进行的轻微额外训练来消除。 添加额外的训练步骤:

减少卷积网络的 Jedi 技术——剪枝

现在我们需要弄清楚何时停止学习<->修剪循环。 当我们需要将网络减少到一定的规模和速度时(例如,对于移动设备),这里可能有一些奇特的选择。 然而,最常见的选择是继续循环,直到误差变得高于可接受的水平。 添加一个条件:

减少卷积网络的 Jedi 技术——剪枝

这样,算法就变得清晰了。 仍有待弄清楚如何确定删除的卷积。

搜索已删除的包

我们需要删除一些卷积。 冲向前去“射击”任何人都是一个坏主意,尽管它会起作用。 但既然你有头脑,你可以思考并尝试选择“弱”卷积来删除。 有几种选择:

  1. 最小 L1 测量或 low_magnitude_pruning。 小权值卷积对最终决策贡献不大的想法
  2. 考虑平均值和标准差的最小 L1 测量。 我们补充了对分布性质的评估。
  3. 屏蔽卷积并排除那些对最终精度影响最小的卷积。 更准确地确定无关紧要的卷积,但非常耗时和资源消耗。
  4. 他人

每个选项都有生命权和其自身的实施特点。 这里我们考虑具有最小 L1 度量的选项

YOLOv3 的手动流程

原始架构包含残余块。 但无论它们对于深度网络来说有多酷,它们都会在一定程度上阻碍我们。 困难在于您无法删除这些层中具有不同索引的对账:

减少卷积网络的 Jedi 技术——剪枝

因此,让我们选择可以自由删除调节的图层:

减少卷积网络的 Jedi 技术——剪枝

现在让我们构建一个工作循环:

  1. 上传激活
  2. 计算出要削减多少
  3. 剪掉它
  4. 学习 10 个 epoch,LR=1e-4
  5. 测试

卸载卷积对于估计我们在某个步骤可以删除多少部分很有用。 卸载示例:

减少卷积网络的 Jedi 技术——剪枝

我们发现几乎所有地方都有 5% 的卷积具有非常低的 L1 范数,我们可以将其删除。 在每一步中,都会重复这种卸载,并评估可以切割哪些层以及多少层。

整个过程分 4 个步骤完成(RTX 2060 Super 的数字在这里和各处):

步骤 MAP75 参数数量,百万 网络大小,MB 从初始值开始,% 运行时间,毫秒 包皮环切情况
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 占全部的 5%
2 0.9625 50 197 83 168 占全部的 5%
3 0.9633 39 155 64 155 对于具有 15 多个卷积的层,为 400%
4 0.9555 31 124 51 146 对于具有 10 多个卷积的层,为 100%

步骤 2 中添加了一个积极的效果——批量大小 4 适合内存,这大大加快了额外训练的过程。
在第 4 步,该过程被停止,因为即使长期额外训练也没有将 mAP75 提高到旧值。
结果,我们设法加快了推理速度 15%,将尺寸减小 35% 并且不完全丢失。

自动化实现更简单的架构

对于更简单的网络架构(没有条件添加、连接和残差块),很可能专注于处理所有卷积层并自动执行裁剪卷积的过程。

我实现了这个选项 这里.
很简单:您只需要一个损失函数、一个优化器和批量生成器:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

如果需要,您可以更改配置参数:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

此外,还实施了基于标准差的限制。 目标是限制被删除的部分,排除具有已经“足够”的 L1 度量的卷积:

减少卷积网络的 Jedi 技术——剪枝

因此,我们允许您仅从与右侧分布类似的分布中删除弱卷积,而不影响从与左侧分布类似的分布中删除:

减少卷积网络的 Jedi 技术——剪枝

当分布接近正态时,pruning_standart_deviation_part系数可以选自:

减少卷积网络的 Jedi 技术——剪枝
我建议假设为 2 西格玛。 或者您可以忽略此功能,保留值 < 1.0。

输出是整个测试的网络大小、损失和网络运行时间的图表,标准化为 1.0。 例如,这里网络大小几乎减少了 2 倍,而质量没有损失(具有 100k 权重的小型卷积网络):

减少卷积网络的 Jedi 技术——剪枝

运行速度会出现正常波动,并且几乎保持不变。 对此有一个解释:

  1. 卷积的数量从方便的(32、64、128)变为对于显卡来说不太方便的 - 27、51 等。 我在这里可能是错的,但很可能它会产生影响。
  2. 该架构并不广泛,但具有一致性。 通过减少宽度,我们不会影响深度。 因此,我们减少了负载,但不改变速度。

因此,改进表现为运行期间 CUDA 负载减少 20-30%,而不是运行时间减少

结果

让我们反思一下。 我们考虑了 2 个剪枝选项 - 用于 YOLOv3(当你必须用手操作时)和用于具有更简单架构的网络。 可以看出,在这两种情况下都可以在不损失精度的情况下实现网络规模的减小和加速。 结果:

  • 减少的大小
  • 加速跑
  • 减少 CUDA 负载
  • 因此,环境友好(我们优化计算资源的未来使用。在某个地方,人们感到高兴 格雷塔·滕伯格)

附录

  • 修剪步骤之后,您可以添加量化(例如,使用 TensorRT)
  • Tensorflow 提供以下功能: 低幅度修剪。 作品。
  • 存储库 我想要发展并且很乐意提供帮助

来源: habr.com

添加评论