2021 神经网络压缩 (李宏毅

news2024/11/28 12:53:59

首先,为什么需要对神经网络模型进行压缩呢?我们在之前的课程中介绍过很多大型的深度学习模型,但当我们想要将这些大模型放在算力比较小的边缘设备或者其他IoT设备里面,就需要对大模型进行压缩。

Lower latency:低时延 Privacy:私密性

介绍5个网络压缩的方法,我们只考虑算法(软件)层面,不考虑硬件层面的解决方法。

 

1. Network Pruning(网络剪枝)

对于一个大的网络来说,我们能想到的是,众多网络参数中一定会有不重要/冗余的一些参数,因此我们将这些参数减掉达到网络压缩的目的。

网络剪枝的步骤如下:首先,我们预训练一个大规模的网络,然后评估里面参数的重要性,包括权重(weight)的重要性和神经元(neuron)的重要性。

  • 评价weight重要性,我们可以用绝对值衡量,即绝对值越大,weight越重要,或者采用之前介绍的life long learning的想法(也許我們也可以就把每個參數的 bi 算出來、就可以知道那個參數重不重要)。
  • 评价neuron重要性,我们可以用其输出的结果为0的次数衡量,即输出0越多越不重要。

接着我们对多余的参数的重要性评估并修剪,得到一个小的网络,再对里面的参数微调,再评估、修剪。。。重复上述过程,直到满足要求,完成Network pruning过程。(一次剪掉大量参数可能对network伤害太大,所以一次只剪掉一点参数比如10%)

刚才提到,修剪的单位有两种,一种是以权重(weight)为单位,一种是以神经元(neuron)为单位,这两者有什么不同呢?实作上差别较大

首先Weight pruning,但这样就造成network 形状不规则(irregular),难以编程实现(pytorch定义network每一層有幾個 Neuron/ vector),同时难以用GPU加速(矩阵乘法)。通常的做法是将冗余的weight置为0,但这样做还是保留了参数(等于0),不是真正去除掉。

在这篇论文中有个关于参数pruning多少与训练速度提升关系的实验验证,其中紫色线sparsity表示参数去掉的量。可以发现,虽然参数去掉了将近95%,但是速度依然没有提升。

(這個 Network Pruning 的方法、其實是一個非常有效率的方法、往往你可以 Prune 到 95% 以上的參數、那但是你的 Accuracy 只掉 1~2% 而已)

接着Neuron pruning,通过去除冗余的神经元,简化网络结构。这样得到的网络结构是规则的,相比于Weight pruning,这种方式更好实现,也更容易通过GPU加速。

Q&A:這個 Pruning 有沒有效率是函式庫的問題?對啦 是函式庫的問題、那如果你可以想辦法寫一個、Irregular的 Network也很有效的函式庫的話、那你就可以用 Weight Pruning、但是 大家都沒有要自己寫函式庫

为什么我们先训练一个大的network,再压缩成一个小的network,而不是直接训练一个小的network呢?一般来说,大的network更容易训练,如果直接训练小的网络可能达不到大的network的训练效果。

why大的network比较好train?参看过去课程录影。这里有个大乐透假说(Lottery Ticket Hypothesis)对上述观点进行了说明。

什么是大乐透假说(Lottery Ticket Hypothesis)呢?

train network是看人品的,每次 Train Network 的結果不一定會一樣,你抽到一組好的 Initial 的參數,就会得到好的结果。

现在有一个训练好的大的网络,可以分解成若干个小的网络,只要某一个小的网络性能与大的网络相同或相似,就说明这个大的网络可以压缩。

大乐透假说在实验上是怎么被证实的呢?

用大樂透假說來解釋上图的现象,就是大network裡面有很多 Sub-network、而這一組 Initialize 的參數,就是幸运的那一组、可以 Train 得起來的 Sub-network

大樂透假說非常知名,在ICLR2019得到 Best Paper Award

关于大乐透假说的一个后续的研究如下,“解构大乐透假说”,通过充分的实验得到了一些有趣的结论:

  • 第一个发现是,尝试了不同的pruning strategy,发现如果训练前和训练后参数的差距越大,将其pruning后得到的结果越有效。
  • 第二个发现是,到底我們今天這一組好的 Initialization好在哪里,   发现说 小的sub-network只要我们不改变参数的正负号,就可以训练起来。说明:正負號是初始化參數 能不能夠訓練起來的關鍵
  • 第三个发现是,对于一个初始的大的网络(因为参数随机初始化很关键),有可能不训练就已经有一个sub-network可以有一个比较好的效果。(其实可以得到跟supervise很接近的正确率)

但是  大乐透假说一定是对的吗?不一定。下面这篇文章就“打脸”了大乐透假说。实验是这样的,我们用pruned完的小网络随机初始化参数,再训练,只要多训练几个epoch,就可以比不随机初始化训练小网络的效果要好。

当然这篇文章的作者也给出了一些对大乐透假说的回应,大乐透假说出现的前提是当learning rate很小,或者unstructured(做Weight pruning )时候才有可能出现大乐透假说现象。

所以大乐透假说,  未來尚待更多的研究來證實

2. Knowledge Distillation

Knowledge Distillation的精神和 Network Pruning 其實也有一些類似的地方

Knowledge Distillation做法如下:首先我们先train一个大网络,叫Teacher Net。student network是去根據這個 Teacher Network 來學習。学生 不是去看這個圖片的正確答案來學習、他把老师的输出 就當做正確答案。

这样做是因为:直接 Train 一個小的 Network 往往結果就是沒有從大的 Pruning 來得好

Knowledge Distillation其实不是新的技术,最知名的文章其实是Hinton在2015年就发表了,

Teacher Net其實會提供這個 Student Network 額外的資訊

那其實 Knowledge Distillation 有些神奇的地方、如果你看那個 Hinton 的 Paper 裡面、它甚至可以做到  光是 Teacher 告訴 Student 哪些數字之間、有什麼樣的關係這件事情、就可以讓 Student在完全沒有看到某些數字的訓練資料下、就可以把那一個數字學會

这个Teacher Net不一定是一个巨大的network,也有可能是将多个network组合(ensemble)得到的。

(ensemble是机器学习比赛里一个非常常用的技巧,你就訓練多個模型  然後你輸出的結果就是多個模型、投票的結果就結束了。或者是把多个模型的输出平均起来,

做个超级ensemble,训练个100 個模型啊1000個模型,把那麼多的模型的結果通通平均起來,往往你要在機器學習的 這種 Leaderboard 上面名列前茅,靠的就是这个技术,

network output上做平均,也可以在network参数上做平均  在translation作业里用过,这一招在translation上不知道为什么特别有用)

 关于Knowledge Distillation的一个小技巧,在softmax函数基础上对每个输出结果加一个超参数T(Temperature),这样会对最后的预测结果进行一个平滑处理,让Student Net更好训练一些。

(softmax就是,你把每一個 Neural 的輸出、都取 Exponential然后再做normalize得到最終 Network 的輸出)

还有人会拿network每一层都拿来train,比如大的有12层,小的6层,可以拿小的第6层像大的12层,小的第3层像大的第6层,往往做比较多的限制,可以得到更好的结果。

3. Parameter Quantization

Parameter Quantization参数量化,也可以称为参数压缩。用比较少的空间来储存一个参数,具体来说有如下几种方式:

  1. 减少参数精度。对于Weight的精度可能不需要太高就可以获得一个比较好的效果,比如从64位调整为32位或者16位等等,这样就可以减少存储的数据量。
  2. Weight clustering(权重聚类):将神经网络所有weight按数值接近进行分群,数值差不多的聚成一类。分几群事先设定好。然后对每个类取一个值(可以是平均值)替换里面所有的权值,相当于每一堆只用一个值就可以存储,这样存储的数据量也大大减少。
  3. 采用信号处理中常用的一种方法:Huffman encoding(哈夫曼编码),常出现的东西用比较少的bit描述,不常出现的东西用比较多的bit描述,这样平均起来存储的数据量将大大减少。

Q&A:Weight Clustering 要怎麼做 Update、每次 Update 都要重新分群嗎?

Weight Clustering其实有个简单做法是,network训练完后、再直接做 Weight Clustering

但直接做,可能会导致 Cluster 後的參數、跟原來的參數相差太大

所以 有一個做法是  我們在訓練的時候要求 Network 的參數 彼此之間比較接近、你可以把這個訓練的 Quantization 當做是Loss 的其中一個環節、直接塞到你的訓練的過程中。让训练中达到 参数有群聚的效果,

Q&A:每個 Cluster 的數字要怎麼決定呢? 就是決定好每個 Cluster 的區間之後取平均。

weight到底可以压缩到什么程度呢?最终极的结果就是,每个weight只需要1bit就可以存下来,  网络中的weight要么是+1,要么是-1,像这样Binary Weights的研究还蛮多的,可以参考的reference如图:

那这样训练出的网络效果会不会不太好?这里有一篇文章是binary network里一个经典的方法Binary Connect,

介绍了该方法用于3种数据集的图像分类问题中,结果发现BinaryConnect的方法识别错误率更小,原文给出的解释是这种方法给network比较大的限制,会在一定程度上减少overfitting情况的发生。

4. Architecture Design(Depth Separable Convolution)

通过network架构的设计 来达到减少参数量的效果,

这里介绍一种关于CNN的减少参数量的结构化设计。

首先回顾一下CNN,在 CNN 的 Convolution Layer 裡、每一個 Layer 的 Input 是一個 Feature Map,  假设输入有2个channel,对应的filter也是2个channel。假设有4个filter,每个filter都是3*3的,那么输出就有4个channel。卷积层共有 3∗3∗2∗4=72 个参数。

接着介绍Depth Separable Convolution,它分为两个步骤:

1. Depthwise Convolution

它在做卷积的时候与传统的对图像做卷积有很大的不同。图片有几个channel就对应有几个filter,每个filter只管一个channel

但是只做Depthwise Convolution会遇到一个问题,channel和channel之间没有任何互动,假设某个pattern是跨channel才能看的出来,这种方法无能为力。

上述过程有 3∗3∗2=18 个参数。

2. Pointwise Convolution

为了解决无法学习输入图像channel与channel之间联系的问题,将Depthwise Convolution的输出结果用 1x1 的filter做卷积,以4个filter为例,效果如下:

上述过程有 2∗4=8 个参数。

将标准CNN和Depth Separable Convolution参数量做对比,可以发现Depth Separable Convolution参数量比CNN要少很多。

那因為 O 通常是一個很大的值、你的 Channel 數目你可能開個 256 啊 512 啊。今天常用的 Kernel Size 可能是 3 x 3 或者是 2 x 2

上述方法为什么有效呢?

过去有一招Low rank approximation,來減少一層 Network 的參數量。如果神经网络某一层输入为N,输出为M(假设非常大),那么对应的weight就有 N∗M 个。这时,如果我们在N和M中间加一层,这一层不用激活函数,直接多插一层,neuron数目是K 。当K比较小时,参数量相比于 N∗M 会大大减少。比如N和M都是1000,K 可以塞個 20、50。但是这样的做法会减少W的可能性,本来W可以放任何参数,拆成这样W的rank ≤ K。

Depth Separable Convolution其实就是用了把 “1层拆成2层 ”这样的概念,相当于将CNN中间多加了一层,这样就可以减少整体网络的参数量。

关于网络结构设计方面还有一些文献参考,感兴趣可以看一下里面相关的内容,这里就不多介绍。

5. Dynamic Computation(动态计算)

在前幾個方法裡面想要做的事情、就是單純的把 Network 變小

而Dynamic Computation让network可以自适应调整计算量,比如让神经网络自适应不同算力的设备,或者同一设备不同电量时对算力的分配。

为什么不在一个设备上放好多个模型呢?因为需要占更多的空间。

如何自适应调整网络的计算量?讓 Network 自由調整它的深度,

这种方式效果到底如何?可以用.. 比较好一点的方法(MSDNet)。

讓 Network 自由决定它的宽度,。

强调一下:是同一個 Network,可以選擇不同的寬度。标一样颜色的就是同一個 Weight

事先决定好 在只要用 75% 參數的時候,某一些neuron不要用到,

训练时 就把所有的狀況一起考慮、然後所有的狀況都得到一個 Output,

上述两种方法都是人为决定根据设备不同的算力(比如电量)动态调整网络深度和宽度,

让network自行决定、根据情景 、決定它的寬度或者是深度。比如,对于不同难度的训练样本可能需要的层数也不一样。

最后总结一下,关于神经网络压缩(Network Compression)的这几种方法,它们并不是互斥的,可以先用某一个方法,再接着用剩余的一个或几个方法,直到满足压缩条件。

 

 

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

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

相关文章

刷题笔记之八(字符串通配符+参数解析+计算日期到天数)

目录 1. dateadd(datepart,number,date)函数是在日期中添加或减去指定的时间间隔 2. DML数据库操作语言负责数据的增删查改 3. 修改表结构的关键字都是alter table 表名,再加修改的语句 4. between and条件查询范围前闭后闭 5. 使用索引…

目标检测(1)—— 基础知识和常用数据集

一、什么是目标检测 一张图片,经过网络后得到输出,检测出感兴趣目标的一个位置,比如下图的车在什么地方,狗在什么地方;还要输出相应位置的目标是什么类别的。 目标检测:位置+类别 矩形框&…

vue 的 render 函数的用法:new Vue({ render: h => h(App), }).$mount(‘#app‘)

render函数的作用 render函数是vue通过js渲染dom结构的函数createElement,约定可以简写为h 官方文档中是这样的,createElement 是 Vue.js 里面的 函数, 这个函数的作用就是生成一个 VNode节点, render 函数得到这个 VNode 节点之后…

记一次内网靶机实战

文章目录0x00 边界服务器0x01 一层网络0x01-01 fscan内网扫描0x01-02 配置frp设置socks5代理0x01-03 访问内网的(10.10.135.66)0x01-04 访问内网的(10.10.135.35)0x01-05 访问内网的(10.10.135.190)0x02二层…

稀疏数组

章节目录:一、稀疏数组1.1 需求引出1.2 基本介绍1.3 应用实例二、结束语一、稀疏数组 1.1 需求引出 假设我们有个五子棋程序,使用1来表示黑子,2表示蓝子,0表示没有棋盘落子,并且需要对棋盘数据进行存储。 前端棋盘示意…

546、Zookeeper详细入门教程系列 -【Zookeeper内部原理】 2022.11.06

目录一、Zookeeper内部原理1.1 节点类型(Znode)1.2 Stat结构体1.3 监听器原理1.4 选举机制1.5 写数据流程二、最后三、参考链接一、Zookeeper内部原理 1.1 节点类型(Znode) 持久:客户端和服务器断开后,创…

汇编语言程序设计 --- 一元二次方程ax2+bx+c=0求解(含注释详细源代码 + 实验报告)

目录一、实验内容二、实验说明三、实验报告要求四、实验目的五、 程序流程图六、内存变化情况七、实验报告 源程序代码 (详细注释)一、实验内容 一元二次方程ax2bxc0求解。 二、实验说明 1、要求在数据段中定义a、b、c、x,a、b、c初值不限…

【晶振专题】案例:为什么对着STM32低速32.768K晶振哈口气就不起振了?

本案例发现在一个工装产品上,首批一共做了10几台样机。发现有的样机在开机的时候读取不到RTC,有的样机却可以。读不到RTC是概率性出现的,发生在第一次上电的情况。开始他怀疑是环境问题,会不会和温度有关,于是同事在家做了大量的实验,发现对晶振吹口气就能让晶振不起振,…

01-nacos在Windows系统单机,集群的安装

一 ,什么是Nacos?官网 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 提供了一组简单易用的特性集,能够快速实现动态服务发现、服务…

Flutter教程之在 Flutter 中显示 TextField 上的日期选择器(教程含源码)

首先我们必须知道它是什么 Flutter 中的日期选择器——Flutter 日期范围选择器是一个轻量级的小部件,它允许用户轻松选择单个日期、多个日期或一个日期范围。日期选择器提供月、年、十年和世纪视图选项,以快速导航到所需的日期。 让我们实现它… 日期选择器—— 我们将在 …

机场调度管理系统(客户端+服务器端+Java+MySQL)

目 录 1 绪论 1 1.1 项目背景 1 1.2 项目目的 1 1.3 项目可行性分析 2 2 技术介绍 3 2.1 Java技术 3 2.1.1 Java技术简介 3 2.1.2 Java面向对象的特征 3 2.2Javascript和jQuery技术 4 2.1.1 Javascript 简介 4 2.2.2 jQuery-easyui简介 4 2.3Jsp技术 5 2.4 Mysql 5 3 需求分析…

python基础05——字典:dict及集合:set,看这篇文章就够了

目录1字典: dict 无序可变序列1.1 创建1.1.1 用{ }创建字典1.1.2 用dict创建字典1.1.3 用zip创建字典1.1.4 用fromkeys创建字典1.2 查询1.2.1 通过键访问字典的值1.2.1.1 直接取键 dict[ ]1.2.1.2 get()1.2.2 查看字典的键和值1.2.2.1 返回所有的键 dict.keys()1.2.2.2 返回所有…

分布式搜索———黑马旅游

案例功能实现 : ● 酒店搜索和分页 ● 酒店结果过滤 ● 我周边的酒店 ● 酒店竞价排名 资源链接 hoteld-demo工程:https://pan.baidu.com/s/1YlKz6vxcm7VWXAWPlUiBqg 提取码:GY66 进入hoteld-demo工程,启动服务,打开浏览器进入…

uniapp微信小程序半屏跳转小程序

1、资料设置申请绑定 进入微信小程序 设置 -> 第三方设置 -> 半屏小程序管理 添加需要绑定的小程序的appid 等待审核,审核通过后开始写代码 2、代码编写 (1)、以前的跳转方式是uni.navigateToMiniProgram 换成wx.openEmbeddedMiniP…

Spring核心思想

文章目录1. Spring核心思想1.1 Spring是什么1.2 什么是容器1.3 什么是loC1.3.1 传统开发1.3.2 如何解决传统开发中耦合度高的问题1.3.3 控制反转程序的编写1.4 理解Spring loC1.5 什么是DI1. Spring核心思想 1.1 Spring是什么 我们通常说的Spring是Spring Framework(Spring框…

一个非常实用的分布式 JVM 监控工具

介绍 该项目为了方便开发者更快监控多个远程主机jvm,如果你的项目是Spring boot那么很方便集成,jar包引入即可,不是Spring boot也不用气馁,你可以快速自行初始化一个Spirng boot程序引入jar包即可 效果展示 整体架构 git地址 ht…

Kafka由浅入深(6) Sender线程执行源码解析

一、KafkaProducer消息流程图 1.1 KafkaProducer 消息架构图 1.2 KafkaProducer 消息架构分为两部分 第一部分是KafkaProducer主线程 主要逻辑提供消息拦截器、序列化器、和分区器的默认实现和对外自定义扩展功能,已经将消息追加并缓存到累加器RecordAccumulator…

NeurIPS 2022 | 涨点神器!利用图像辅助三维点云分析的训练新范式

原文链接:https://www.techbeat.net/article-info?id4212 作者:颜旭 点云作为一种基本的三维表征形式,活跃在自动驾驶、机器人感知等多种任务上。尽管三维点云分析在近年来取得了良好的发展,但由于点云其本身往往是无序、无纹理以…

OpenCV笔记--人脸识别算法Eigenfaces和Fisherfaces

目录 1--前言 2--处理ORL数据集 3--Eigenfaces复现过程 4--Fisherfaces复现过程 5--分析 1--前言 ①SYSU模式识别课程作业 ②配置:基于Windows11、OpenCV4.5.5、VSCode、CMake(参考OpenCV配置方式) ③原理及源码介绍:Face…

云栖探馆!云小宝首秀遇上老司机小龙,猜猜谁赢了?

为啥人人都喜欢秋天呢?因为我们打喷嚏都是“爱秋”啊~ 为啥大家会来云栖大会呢?因为云栖大会让我们在一“栖”啊~ 2022云栖大会龙蜥峰会,小龙来啦~! ​ 去年,小龙作为萌新来到云栖大会&#…