网络压缩之网络剪枝(network pruning)

news2024/11/14 13:48:31

        网络剪枝(network pruning)就是要把网络里面的一些参数剪掉。剪枝就是修剪的意思,把网络里面的一些参数剪掉。为什么可以把网络里面的一些参数剪 掉呢?这么大的网络里面有很多很多的参数,每一个参数不一定都有在做事。参数这么多的 时候,也许很多参数只是在划水,什么事也没有做。这些没有做的参数放在那边,就只是占空 间而已,浪费计算资源而已。为何就把它们剪掉呢?所以网络剪枝就是把一个大的网络中没 有用的那些参数把它找出来,把它扔掉。人刚出生的时候,脑袋是空空的,神经元跟神经元间 没什么连接。在六岁的时候会长出非常多的连接。但是随着年龄渐长,有一些连接就慢慢消 失了。这个跟网络剪枝有异曲同工之妙。网络剪枝不是太新的概念,早在这个90年代,Yann Le Cun 的论文“Optimal Brain Damage”是讲网络剪枝,他把大脑(网络)剪枝,把它剪掉一 些权重看成是一种脑损伤,最优的意思是要找出最好的剪枝的方法,让一些权重被剪掉之后, 但是对这个脑的损伤是最小的。

        网络剪枝其框架如图1所示,首先,先训练一个大的网络。接下来去衡量这个大的网 络里面每一个参数或者是每一个神经元的重要性,去评估一下有没有哪些参数是没在做事的, 或有没有哪些神经元是没在做事的。怎么评估某一个参数有没有在做事呢,怎么评估某一个 参数重不重要呢。最简单的方法也许就是看它的绝对值。如果这个参数的绝对值越大,它可 能越能对整个网络的影响越大。或者如果它的绝对值越接近零。也许对整个网络的影响越小, 也许对我们任务的影响越小。

图1 剪枝框架

        为什么不一次剪掉大量的参数,因为在实验上,如果一次剪掉大量的参数,可能对网络的 伤害太大了,可能会大到用微调也没有办法复原。所以一次先剪掉一点参数。比如说只剪掉 10% 的参数,然后再重新训练,然后再重新剪掉10%的参数,再重新训练,反复这一个过程。 我们可以剪掉比较多的参数,当网络够小以后,整个过程就完成了,就得到一个比较小的网 络。而且这个比较小的网络,也许它的正确率跟大的网络是没有太大的差别的。修剪的单位可 以以参数为单位,也可以以神经元来当作单位,这两者作为单位,在实现上会是有显著不同。 如果我们现在是以参数当作单位会发生什么事,假设我们是要评估某一个参数要不要被去掉, 某个参数对整个任务而言重不重要能不能够被去掉,我们把这个不重要的参数去掉以后,得 到的网络的形状可能会是不规则的。如图2所示,所谓不规则的意思是说,举例来说,红 色的这个神经元连到接下来三个绿色的神经元,但第二个红色的神经元只连到两个绿色的神 经元。或这个红色的神经元的输入只有两个蓝色的神经元,而这个红色的神经元的输入有四 个蓝色的神经元。如果把参数当作单位来进行修剪的话,修剪完以后的网络的形状会是不规则的。

图2 枝的问题

        形状不规则最大的问题就是不好实现。用PyTorch要实现这种形状不规则的网络,不好 实现。因为在PyTorch里面,定义第一个网络的时候,定义方法都是每一层有几个神经元,定 义现在每一层要输入几个输入,输入有几个神经元,输出有几个神经元。或者输入多长的向 量,输出有多长的向量。这种形状不固定的网络根本不好实现,而且就算硬是把这种形状不规 则的网络实现出来,用GPU也很难加速。GPU在加速的时候,就是把网络的计算看成一个 矩阵的乘法,但是当网络是不规则的时候,不容易用矩阵的乘法来进行加速,我们不容易用 GPU 来进行加速,所以实际在做权重剪枝的时候,在实现上我们可能会把那些修剪掉的权重 直接补零,就是修剪掉的权重不是不存在,它的值只是设为零。这样的好处是实现就比较容 易,比较容易用GPU加速,但根本就没有真的把网络变小,虽然权重值是零,但还是存了这 个参数,我们还是存了一个参数在内存里面,并没有真的把网络变小。这是以参数为单位来做 剪枝的时候,实现上会遇到的问题。

        如图3 所示,紫色的这一条线是指稀疏程度(sparsity)。稀疏程度就是有多少百分比 的参数现在被修剪掉了。紫色的这条线的值都很接近1,代表有接近大概95%以上的参数都 被修剪掉了。网络剪枝其实是一个非常有效率的方法,往往可以修剪到95%以上的参数,但 是准确率只掉12%而已。所以这边参数修剪时,有95%的参数都被丢掉了,只剩下5%的 参数,这个网络变得很小,的计算要很快吧。但实际上我们发现根本就没有加速多少,甚至可 以说根本就没有加速。图17.3中的长条图显示的是在三种不同的计算资源上面,加速的程度。 加速的程度要大过1才有加速,加速程度小于1其实是变慢的。在多数情况下根本就没有加 速,多数情况下其实都是变慢,也就是把一些权重修剪掉,结果网络形状变得不规则,真的用 GPU 加速的时候,反而没有办法真的加速它,所以权重剪枝不一定是一个特别有效的方法。

图3 权重剪枝无法用GPU加速

        神经元剪枝,即以神经元为单位来做剪枝也许是一个比较有效的方法。如果用神经元做 单位来剪枝,丢掉一些神经元以后,网络的架构仍然是规则的。这种用PyTorch也比较好实现,实现的时候,只要改那个每一个层输入、输出的那个维度就好了,也比较好用GPU来加速。

        接下来要问一个问题:我们先训练一个大的网络,再把它变小,而且说小的网络跟大的网 络的正确率没有差太多。不直接训练一个小的网络就好了,直接训练一个小的网络比较有效 率,还训练大的网络变小干嘛,根本是舍本逐末,为什么不直接训练小的网络?一个普遍的答 案是大的网络比较好训练。如果直接训练一个小的网络,往往没有办法得到跟大的网络一样 的正确率。我们可以先训练一个大的网络,再把它变小,正确率没有掉太多。但直接训练小的 网络,得不到大的网络剪枝完变得小的网络一样的正确率。

        为什么大的网络比较好训练?有一个假说叫做彩票假说(lottery ticket hypothesis)。假 说代表说它不算是一个被实证的理论。但它现在只是一个假说而已,这个彩票假说是怎么解 释为什么大的网络比较容易训练,直接训练一个小的网络没有办法得到跟大的网络一样的效 果,一定要大的网络剪枝变小,结果才会好。彩票假说是这样说的,每次训练网络的结果不一 定会一样。我们抽到一组好的初始的参数,就会得到好的结果;抽到一组坏初始的参数,就会 得到坏的结果。但如何在彩票这个游戏里面得到比较高的中奖率,是不是就是包牌买比较多 的彩券,可以增加中奖率,所以对一个大的网络来说也是一样的。大的网络可以视为是很多小 的子网络(sub-network)的组合。如图 4 所示,我们可以想成是一个大的网络里面其实包 含了很多小的网络。训练这个大的网络的时候,等于同时训练很多小的网络。每一个小的网络 不一定可以成功的被训练出来。所谓成功的训练出来是说它不一定可以,通过梯度下降找到 一个好的解,不一定可以训练出一个好的结果,不一定可以让它的损失变低。但是在众多的子 网络里面,只要其中一个子网络成功,大的网络就成功了。而如果大的网络里面包含的小的 网络越多,就好像是去买彩票的时候,买比较多的彩券一样,彩券越多,中奖的概率就越高。 一个网络越大,它就越有可能成功的被训练起来。彩票假说在实验上是怎么被证实的?它在实 验上的证实方式跟网络的剪枝非常有关系,所以直接看一下在实验上是怎么证实彩票假说的。

图 4 大网络包含了很多小网络

如图5 所示,现在有一个大的网络,在这个大的网络上面一开始的参数是随机初始化。 把参数随机初始化以后,得到一组训练完的参数。训练完的参数用紫色来表示,接下来用网络 剪枝的技术,把一些紫色的参数丢掉,而得到一个比较小的网络。如果直接把这个小的网络里面的参数,再重新随机的去初始化,也就是重训练一个一样大小的小的网络,就是我们把这个 网络复制一次。但是参数完全不一样,重新再训练一次。重新再训练一次,直接训练这个小的 网络,训练不起来,训练一个大的再把它变小,没问题。但假设这一个小的网络,再重新初始 化参数的时候,我们用的跟这组红色的参数是一模一样的,就训练得起来。

图5 彩票假说

        这两组参数虽然都是随机初始化的,但是这组绿色的参数跟这组红色的参数是没有关系 的。而这边这些随机初始化的参数是直接从这边的红色参数里面选出对应的参数,就是这边 有四个参数。我们就是把这边对应到的这四个参数直接把它复制过来,这边有四个参数。我 们就把这里面对应到的四个参数直接复制过来,把这里面的参数直接复制过来就训练了起来。 如果用彩票假说来解释的话,就是这里面有很多子网络。而这一组初始化的参数,就是幸运的 那一组可以训练得起来的子网络,所以用把这些网络,把这个大的网络训练完,再剪枝掉的时 候,留下来的就是幸运的那些参数,可以训练得起来的那些参数,所以这一组初始化的参数是 可以训练得起来的一个子网络。但是如果我们再重新随机初始化的话,就抽不到可以成功训 练起来的参数,所以这个就是彩票假说。彩票假说非常地知名,它得到了ICLR2019的最佳 论文奖。

        后面也有很多后续的研究,比如说有一篇有趣的研究叫做“Deconstructing Lottery Tick ets: Zeros, Signs, and the Supermask”。解构这个彩票有什么有趣的结论,直接讲它的结论。 第一个试了不同的剪枝策略,它做了一个非常完整的实验发现说,如果训练前跟训练后权重 绝对值差距越大,剪枝那些网络得到的结果是越有效的。另外一个比较有趣的结果是,到底这 一组好的初始化是好在哪里呢?如果我们只要不改变参数的正负号,就可以训练起来,小的网 络只要不改变正负号,就可以训练起来。假设剪枝完以后,剩下的这个数。假设剪枝完以后, 再把原来随机初始化的那些参数拿出来,它的值是0.9,3.1,−9.1,8.5,可以完全不管它的数值, 直接把正的数值的通通都用+α来取代,小于0的都用−α来取代,即+α,+α,−α,+α。

        用这组参数去初始化模型,这样也训练得起来,会跟用这组参数去初始化差不多。所以这 个实验告诉我们说正负号是初始化参数,能不能够训练起来的关键,它的绝对值不重要,正负 号才重要。

        最后一个神奇的发现是,既然我们在想说一个大的网络里面有一些网络有一些子网络,它 是特别是好的初始化的参数,它训练起来会特别地顺利。会不会一个大的网络里面甚至其实 已经有一个子网络,它连训练都不用训练,直接拿出来就是一个好的网络呢?我们完全不用训 练网络,直接把大的网络剪枝,就得到一个可以拿来做分类的分类器了,有没有可能是这个样 子的呢。就好像米开朗基罗说:“塑像就在石头里,我只是把不需要的部分去掉”,会不会在整 个大的网络里面,算参数都是随机的,其中已经有一组参数,它就已经可以做分类了,把多余 的东西拿掉,直接就可以得到好的分类结果的。 但是彩票假说不一定是对的,论文“Rethinking the Value of Network Pruning” 是打脸 彩票假说,而且神奇的是这篇文章跟彩票假说是同时出来的,它们同时出现在ICLR2019,它 们得到了不太一样的结论。这篇文章试了两个数据集,还有好几种不同的模型,这个是没有剪 枝过的网络的正确率,然后它试着去剪枝了一下网络,再重新去做微调。小的网络可以跟大的 网络得到差不多的正确率。然后它说一般人的想像是,如果直接去训练小的网络,正确率会不 如大的网络剪枝完以后的结果。 其实在这篇文章里面也有对彩票假说做出一些回应,它觉得彩票假说观察到的现象,也 许只有在某一些特定的情况下才观察得到。根据这篇文章的实验,只有在学习率设比较小的 时候,还有非结构化的(unstructured)的时候,就是剪枝的时候是以权重作为单位来做剪枝 的时候,才能观察到彩票假说的现象,它发现说学习率调大,它就观察不到彩票假说的这个现 象,所以到底彩票假说的正确性尚待更多的研究来证实。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AcWing 897. 最长公共子序列

动态规划就是多见识应用题就完事儿了&#xff0c;也没有什么好说的。 讲解参考&#xff1a; 【E05 线性DP 最长公共子序列】 #include<iostream> #include<algorithm> #define N 1010 using namespace std; char a[N],b[N]; int n,m; int f[N][N]; int main(){…

欧拉 函数

互质&#xff1a; 互质是公约数只有1的两个整数&#xff0c;叫做互质整数。公约数只有1的两个自然数&#xff0c;叫做互质自然数&#xff0c;后者是前者特殊情况。 &#xff08;1和-1与所有整数互质&#xff0c;而且它们是唯一与0互质的整数&#xff09; 互质的判断方法&…

微信公众号文章导出工具 100%还原原文样式:wechat-article-exporter

wechat-article-exporter是一款微信公众号文章导出工具&#xff0c;能够100%还原原文样式&#xff0c;工具受 WeChat_Article 项目的启发所写&#xff0c;目前支持 搜索公众号和公众号内文章&#xff0c;导出文章为包含图片和样式文件的HTML格式&#xff08; (打包了图片和样式…

中仕公考:这样备考,你天生就是公务员!

根据上岸学员的反馈&#xff0c;小编发现了一些共通点&#xff0c;无论是在职备考还是全职备考&#xff0c;只要做到以下几点&#xff0c;不上岸那是不可能的! 1. 作息规律&#xff0c;早起不熬大夜。每天按时早起&#xff0c;挤出时间用来学习&#xff0c;晚上不熬夜学习到很…

Windows编程系列:PE文件结构

Windows编程系列&#xff1a;PE文件结构 PE文件结构 Portable Executable (PE)&#xff0c;可移植的可执行文件。在Windows平台下&#xff0c;所有的可执行文件&#xff08;包括.exe, .dll, .sys, .ocx, .com等&#xff09;均使用PE文件结构。这些使用了PE文件结构的可执行文…

HarmonyOS开发实战( Beta5版)应用性能工具CPU Profiler的使用规范

简介 本文档介绍应用性能分析工具CPU Profiler的使用方法&#xff0c;该工具为开发者提供性能采样分析手段&#xff0c;可在不插桩情况下获取调用栈上各层函数的执行时间&#xff0c;并展示在时间轴上。 开发者可通过该工具查看TS/JS代码及NAPI代码执行过程中的时序及耗时情况…

Web-gpt

AJAX AJAX&#xff08;Asynchronous JavaScript and XML&#xff0c;异步JavaScript和XML&#xff09;是一种用于创建动态网页应用的技术。它允许网页在不重新加载整个页面的情况下&#xff0c;异步地从服务器请求数据&#xff0c;并将这些数据更新到网页上。这提高了用户体验…

HarmonyOS开发实战( Beta5版)小程序场景性能优化开发指导

简介 小程序是一种轻量级的应用&#xff0c;它不需要下载、安装即可使用&#xff0c;用户可以通过扫描二维码或者搜索直接打开使用。小程序运行在特定的平台上&#xff0c;平台提供了小程序的运行环境&#xff08;运行容器&#xff09;和一些基础服务&#xff08;小程序API&am…

【C++ 第十八章】C++11 新增语法(2)

前情回顾&#xff1a; 【C11 新增语法&#xff08;1&#xff09;&#xff1a;1~6 点】 C11出现与历史、花括号统一初始化、initializer_list初始化列表、 auto、decltype、nullptr、STL的一些新变化 本文会使用到自己模拟实现的 string 和 list 类&#xff0c;为了更好的观察各…

笔记整理—内核!启动!—uboot部分(2)

上文中&#xff0c;我们说到了使用uboot去启动kernel支持的几种方式以及压缩kernel的几种形式&#xff0c;本章节将要接着内核的启动说起。 上一章我们对uImage格式进行了初步的说明&#xff0c;并说这样的格式已经被废弃&#xff0c;但是依然保留了相应的代码。boot_get_kerne…

MATLAB生成mif文件

MATLAB代码 % 参数设置 N 4096; % 数据点数量 t linspace(0, 2*pi, N); % 时间向量 width 12; % 位宽% 正弦波 sine_wave 2.5 * sin(t) 2.5; % 幅度在0到5之间% 三角波 tri_wave 5 - abs(mod(t/(2*pi)*4, 2) - 1);% 方波 square_wave 2.5 * (square(t) 1); % 将范围调…

Hive Tutorial For Beginners

Hive Tutorial For Beginners 一、Hive历史&#xff08;History of Hive&#xff09; Facebook 在面对日益增长的大数据时&#xff0c;选择了 Hadoop 作为解决方案。 但问题在于&#xff0c;许多用户并不熟悉 Java 或其他编程语言&#xff0c;这使得使用 Hadoop 的 MapReduc…

代码随想录——回文子串(Leetcode 647)

题目链接 我的题解&#xff08;双指针&#xff09; 思路&#xff1a; 当然&#xff0c;以下是对您提供的代码的解释&#xff1a; class Solution {public int countSubstrings(String s) {// 初始化回文子字符串的数量int count 0;// 遍历字符串的每个字符&#xff0c;使用…

无人机之电池篇

无人机电池作为无人机的重要组成部分&#xff0c;其性能、使用、保养及选择都至关重要。以下是对无人机电池的综合介绍&#xff1a; 一、无人机电池的基本参数 电池容量&#xff1a;电池容量直接影响无人机的续航能力。大容量电池&#xff0c;如5000mAh的电池&#xff0c;能提…

无人机道通布局的讲究详解!!!

一、通道分配与功能对应 基本通道&#xff1a;无人机遥控器通常至少包含四个基本通道&#xff0c;分别对应无人机的上下&#xff08;升降&#xff09;、左右&#xff08;副翼&#xff09;、前后&#xff08;俯仰&#xff09;和旋转&#xff08;方向舵&#xff09;控制。这些通…

关于报错 SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“ 的可能原因

1. 絮絮叨叨 学习或工作中&#xff0c;如果需要从头建立日志打印体系&#xff0c;笔者通常直接照抄之前的博客&#xff1a;《Java maven工程配置slf4j》&#xff0c;直接粘贴、复制相关依赖除了上述博客提到的slf4j-api、logback-classic&#xff0c;也看到过slf4j-simple、lo…

区域生长算法详解与Python实现

图像分割是计算机视觉中一个重要的任务&#xff0c;区域生长算法是其中的一种常见方法。本文将详细介绍区域生长算法的原理&#xff0c;并通过Python代码实现&#xff0c;带你一步步理解它的实际应用。 1. 区域生长算法简介 区域生长算法是一种基于像素相似性进行图像分割的方…

2025款宋L EV全面升级加量不加价,仅18.98万元起

8月30日&#xff0c;2024成都车展正式开幕&#xff0c;备受期待的比亚迪王朝网B级先锋猎装SUV——2025款宋L EV正式上市&#xff0c;搭载“天神之眼”高阶智能驾驶辅助系统DiPilot 100&#xff0c;e平台3.0、CTB、云辇-C三大明星技术&#xff0c;并新增外观内饰配色。凭借智驾、…

【2024】Datawhale X 李宏毅苹果书 AI夏令营 Task2

本文是关于李宏毅苹果书”线性模型“学习内容的记录。 线性模型 线性模型&#xff08;linear model&#xff09;&#xff1a;将输入的特征 x x x&#xff08;或 x \bold{x} x&#xff09;乘上权重 ω \omega ω&#xff08;或 ω \bold{\omega} ω&#xff09;&#xff0c;再…

Python简易IDE工作界面制作

、 休闲一下&#xff0c;学习编程还是要学习一些界面编程&#xff0c;能够根据需要制作图形操作界面&#xff0c;这样我们开发的程序才能方便操作和使用&#xff0c;同时获得更友好的人机交互体验。下面是一个用PyQt5制作的简易界面&#xff0c;供大学参考。如下图所示&a…