zoukankan      html  css  js  c++  java
  • 李宏毅机器学习课程笔记-13.1模型压缩之网络剪枝

    Motivation

    网络剪枝(Network Pruning)就是删除一个较大网络中的一些weight或neuron得到一个更小的网络。

    我们相信,通常情况下我们训练出的神经网络是over-parameterized,即其中存在很多weight或neuron是没有用的(比如有些neuron的输出总是0、有些weight非常接近0) ,因此我们可以把这些没有用的weight或neuron剪掉。

    在90年代,Yann Le Cun就提出了“网络剪枝”,paper名称为Optimal Brain Damage。

    有个问题是:为什么不直接使用较小Network而是对较大Network进行剪枝?常见的解释是:较小的Network训练出来的结果一般都不好,而较大的Network更容易optimize(李老师这个视频有讲解为什么:https://www.youtube.com/watch?v=_VuWvQUMQVk)。在训练神经网络时可能会遇到local minima和saddle point的问题,但如果Network够大这种问题就会不那么严重,现在有很多文献甚至可以证明只要Network够大就可以用梯度下降找到global optimal。

    How to Prune a Network

    1. 训练出一个较大的Network

    2. 评估该Network中每个weight和neuron的重要性

      这一步有很多种做法

      • weight的重要性

        比如:如果其值接近0,则说明该weight不重要,因此可以计算weight的L1或L2判断weight的重要性。

      • neuron的重要性

        比如:给定dataset,如果某个neural的输出都是0那么该neural是不那么重要的

    3. 根据重要性将weight和neuron排序并删除那些不那么重要的weight和neuron

      删除一些weight和neuron后,Network会变小但精度一般也会变低,因此还需要进行fine-tune

      一次最好不要删除太多neuron或weight,否则Network的精度会无法通过fine-tune恢复,最好是每次只删除一小部分然后进行fine-tune并重复该过程

    4. fine-tune

      训练剪枝得到的较小的网络

    熟悉YOLO的读者,可以根据这个仓库(https://github.com/tanluren/yolov3-channel-and-layer-pruning)感受一下剪枝和知识蒸馏。

    Lottery Ticket Hypothesis

    论文链接:https://arxiv.org/abs/1803.03635,这是ICLR2019的一篇论文

    如下图所示,现有一个较大网络A,随机初始化其参数并记该参数为W,训练该较大网络A并进行剪枝得到较小网络B。有个现象是:如果我们随机初始化较小网络B的参数并进行训练,得到的结果就不行;但如果使用参数W中的对应参数初始化,得到的结果就可以。

    img

    Rethinking the Value of Network Pruning

    论文链接:https://arxiv.org/abs/1810.05270,这是ICLR2019的一篇论文

    这篇论文的结论和Lottery Ticket Hypothesis一文相反:现有剪枝后的网络,将其参数随机初始化是可以训练出好的结果的。

    ICLR2019的review是开放的,网上可以搜到两篇文章作者的讨论,知乎上也有关于这两篇论文的讨论,后续也有人做了相关研究。

    Some Issue in Weight Pruning

    如果是weight pruning,那剪枝后的Network会变得不规则(比如有些neuron有2个weight而有些neuron有4个weight)。这样的不规则的Network是不好用keras等代码框架实现的,并且GPU只能对矩阵运算进行加速而无法加速这样的Network。比较常见的实做方法是将需要剪掉的weight设成0,因此仍然可以用GPU加速,但这样其实并没有使网络变小。

    实际上做weight pruning是很麻烦的,通常都进行neuron pruning,因为比较容易用代码实现、也容易达到加速的目的。


    Github(github.com):@chouxianyu

    Github Pages(github.io):@臭咸鱼

    知乎(zhihu.com):@臭咸鱼

    博客园(cnblogs.com):@臭咸鱼

    B站(bilibili.com):@绝版臭咸鱼

    微信公众号:@臭咸鱼

    转载请注明出处,欢迎讨论和交流!


  • 相关阅读:
    android自定义Dialog
    go笔记-内存回收分析、内存统计信息字段释义
    go笔记-defer以及性能
    go笔记-goroutine和panic
    并发编程-高性能IO-reactor模式
    go笔记-查看coredump:delve调试工具
    IO多路复用[转]
    kubernates 1.20.6安装
    JavaScript 数组元素的一些操作
    如何理解 Java 多线程
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/14725232.html
Copyright © 2011-2022 走看看