2021 神经网络压缩 (李宏毅

2023-05-16

首先,为什么需要对神经网络模型进行压缩呢?我们在之前的课程中介绍过很多大型的深度学习模型,但当我们想要将这些大模型放在算力比较小的边缘设备或者其他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)的这几种方法,它们并不是互斥的,可以先用某一个方法,再接着用剩余的一个或几个方法,直到满足压缩条件。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021 神经网络压缩 (李宏毅 的相关文章

  • [云计算]OpenStack - Neutron

    Neutron在OpenStack中的位置 可以为虚拟机或者 OpenStack 组件提供网络服务 xff0c xff08 由 Nova network 独立出来的 xff09 随着需承载业务的能力的增长作为 Nova 子组件无法满足 过程
  • 后台架构师除了技术,还有97件事,你知道吗?

    对于架构师 xff0c 很多人可能觉得很笼统 架构师到底需要学习什么 xff1f 学习完哪些技术就可以到架构师的水准 在行业内的话其实并没有一个非常明确的标准 技术是一方面 xff0c 但是如果仅仅只是技术的话 xff0c 具体一名合格的架
  • Failed to read artifact descriptor for xxx.jar

    mavne 项目 pom xml 文件标红 错误如下 xff1a Failed to read artifact descriptor for xxx jar Failed to read artifact descriptor for x
  • imx6q平台上移植mt7601

    本文描述如何将MT7601 WiFi模块移植到IMX6Q开发板上 xff0c 分析移植过程中碰到的问题 xff0c 分析错误原因 xff0c 提供解决办法 一 MT7601实物图 二 验证开发板和USB MT7601硬件是否正常 步骤1 x
  • 在图片上画出标注目标框和类别python程序

    在图片上画出标注目标框和类别python程序 xff0c 还是比较简单的 xff0c 直接上一份代码 xff1a usr bin python coding UTF 8 2018 07 11 by DQ import cv2 import
  • iOS性能监控及自动化测试辅助工具对比-tidevice、py-ios-device(pyidevice)、sonic-ios-bridge(sib)

    对比项 tidevice py ios device xff08 pyidevice xff09 sonic ios bridge xff08 sib xff09 是否开源 github地址 https github com alibaba
  • git中tag与release的创建以及两者的区别

    简介 本文辨析在参与开源项目时会遇到的tag与release的概念区别与联系 xff0c 并比较两者的创建方法 定义 标签 xff08 tag xff09 是特定提交 xff08 commit 一个指针 xff0c 也就是每个tag对应一个
  • 如何评价数仓好坏

    评价一个数仓的好坏可以涉及相当多的维度 xff0c 这里简单分享一些在实习时了解到的比较看重的方面 模型合理性 一个数仓模型的诞生往往是为了满足产品提出来的业务需求 xff0c 但是如果一个模型仅仅只能做到完全为这一次需求而服务的话 xff
  • 数据倾斜的判断方法和解决方案

    数据倾斜的判断方法 首先点开任务的sparkUI界面中的Stages xff0c 对Duration一列进行排序 xff0c 观察看有没有某个stage出现运行时间远大于其它stage的情况出现 xff0c 假设有的话 xff0c 就点开D
  • 数据开发中的资源管理优化(spark运行)

    在数据开发中 xff0c 资源管理主要看关注于队列整体的CPU使用率 xff0c 内存使用率或者单个任务的CPU使用率 xff0c 内存使用率 CPU使用率 默认情况下是一个core执行一个task 如果此时CPU利用率过低 xff0c 那
  • 互联网大厂SQL真题(二)

    题目 xff1a 每天的日活数及新用户占比 新用户占比 61 当天的新用户数 当天活跃用户数 xff08 日活数 xff09 如果in time 进入时间和out time 离开时间跨天了 xff0c 在两天里都记为该用户活跃过 新用户占比
  • 互联网大厂SQL真题(三)

    题目 xff1a 近一个月发布的视频中热度最高的top3视频 问题 xff1a 找出近一个月发布的视频中热度最高的top3视频 注 xff1a 热度 61 a 视频完播率 43 b 点赞数 43 c 评论数 43 d 转发数 新鲜度 xff
  • Spark三种常见JOIN方式

    Spark join 基本原理 Spark join的基本实现流程如下图所示 xff0c Spark将参与Join的两张表抽象为流式表 StreamTable 和查找表 BuildTable xff0c 通常系统会默认设置StreamTab
  • 遛一遛8266的定时器

    一 xff1a 简述 硬件为ESP LAUNCHER开发板 使用GPIO12 要求是某一定时间指示灯状态发生改变 ESP8266定时功能的实现有两种方式 xff1a 软件定时器和硬件定时器 软件定时器的接口在 ESP8266 NONOS S
  • MYSQL8.0以上版本忘记ROOT密码

    MYSQL8 0 43 忘记Root密码 xff1a 1 以超级管理员打开cmd xff0c 关闭mysql服务2 跳过权限验证登录mysql3 在新的窗口中登录mysql4 切换到mysql xff0c 将密码置空 5 设置加密规则并更新
  • 深度学习【13】tensorflow保存graph和参数为pb文件

    from tensorflow python framework graph util import convert variables to constants graph 61 convert variables to constant
  • plsql查询数据显示为乱码解决方法

    使用plsql查询数据显示为乱码 xff1a 查看数据库编码 xff1a 通过网上搜索 xff0c 发现需要设置环境变量 xff0c 添加以下环境变量 xff1a LANG 61 zh CN GBK NLS LANG 61 34 SIMPL
  • 对抗网络之目标检测应用:A-Fast-RCNN

    对抗网络之目标检测应用 xff1a A Fast RCNN 论文 xff1a A Fast RCNN Hard Positive Generation via Adversary for Object Detection 点击下载 Caff
  • make -j20 出现以下报错: Ensure Jack server is installed and started

    如果出现的报错是 xff1a build core ninja mk 148 recipe for target 39 ninja wrapper 39 failed 综上所述 xff0c 其实就是 xff1a Android7 0 xff
  • QT中 窗口部件的 背景图片 的设置

    QT中 窗口部件的 背景图片 的设置 分类 xff1a QT 2013 04 08 11 06 359人阅读 评论 0 收藏 举报 目录 43 如何设置对话框的自定义的背景颜色 xff1f 2010 03 14 14 34 11 分类 xf

随机推荐

  • 刷LeetCode的一些心得(0基础大龄转码上谷歌)

    我之前就是完全0基础 大龄转码 xff0c 刷题上千然后进谷歌的 这里0基础指的是没学过编程语言 xff0c 没学过数据结构和算法 xff0c 一上来就直接做题那种 第一道题two sum xff0c 我显然不会做 我的笨方法就是看答案 x
  • 在Centos8 中使用Stratis管理本地存储(一)

    导读Stratis是RHEL8 Centos8中提供的一个新的本地存储管理工具 xff0c 它将有助于在块设备上创建分层存储 在RHEL8 Centos8中 xff0c 可以通过安装两个软件包获得Stratis 在RHEL7 xff0c 我
  • ncat命令使用实例

    导读Ncat工具功能类似于cat命令 xff0c 但用于网络 它是一个命令行的工具 xff0c 用于跨网络读取 写入和重定向数据 它被设计成一个可靠的后端工具 xff0c 可以与脚本或其他程序一起使用 ncat可以是端口扫描工具 xff0c
  • Ubuntu 20.04 使用realmd加入AD域

    导读本文展示如何使用 realmd sssd将 Ubuntu 20 04加入到 Active Directory 域 本文还进一步为通过 AD 登录的域用户配置 sudo 规则 设置主机名和DNS 下面命令用来设置正确的主机名和dns服务器
  • Linux下合并文件

    导读 我们在先前的文章中介绍过 cat 命令 的使用 xff0c 了解到该 命令 用于获取文件内容并将其输出到屏幕或其他设备中 事实上 xff0c cat 命令的最初目的是连接文件 xff0c 所以我们可以用它来合并文件 我们在先前的文章中
  • 私有云有哪些优势?

    导读从RightScale 2017的报告中我们发现 xff0c 平均每家公司正在使用1 8个公有云和2 3个私有云 xff0c 同时正在准备使用1 8个公有云和2 1和私有云 从这项数据中我们不难发现 xff0c 公司对于私有云的使用程度
  • 通过sonic-ci-helper插件与Sonic平台结合实现多设备批量安装应用

    一 sonic ci helper 插件 sonic ci helper 是为对接Jenkins CI流程建设的小助手 下载地址 xff1a Sonic Download Center 两种安装方式 xff1a xff08 1 xff09
  • 在Centos8 中使用Stratis管理本地存储(二)

    本文介绍如何通过向现有Stratis池中添加新磁盘和添加缓存磁盘 下面将介绍添加 删除 快照等内容 系统环境 Centos8 向Stratis池中添加其他磁盘 在Stratis管理下 xff0c 将新的块设备添加到现有池非常容易 在上一篇文
  • ubuntu升级后,停留在tty1界面,进不去桌面

    ubuntu升级后 xff0c 提示输入用户名 密码 xff0c 出现以下界面 xff1a 无法显示桌面 输入startx xff0c 即可进入桌面
  • Debian 无法拉取 https 源 -----清华源Debind-stretch

    已经配置好的清华源tsinghua sources Debind stretch可以直接docker pull 无法拉取 https 源 Debian 的软件源配置文件是 etc apt sources list 将系统自带的该文件做个备份
  • 阿里云弹性计算资源

    1 弹性计算 1 1 轻量级应用服务器 针对轻量级应用而生 xff0c 共享容器化的服务器 xff0c 使用个人网站 中小企业网站 个人博客等应用 1 2 企业级服务器 xff08 ECS xff09 企业场景对业务稳定性的要求高 xff0
  • tensorflow2的GPU版本安装

    一 安装Anaconda与Python 详情直接参考我的这篇文章Anaconda安装与配置 二 安装CUDA 1 首先查看本机GPU对应的cuda版本 xff0c 如下图所示 xff0c 本机cuda版本为11 6 xff0c 后面选择的c
  • C#控件及常用设计整

    1 窗体 1 2 Label 控件 3 3 TextBox 控件 4 4 RichTextBox控件 5 5 NumericUpDown 控件 7 6 Button 控件 7 7 GroupBox 控件 7 8 RadioButton控件
  • 五、中断服务程序的流程

    1 中断服务程序的流程 保护现场 中断服务 恢复现场 中断返回 保护现场 xff1a 程序断点的保护 xff08 中断隐指令完成 xff09 xff0c 寄存器内容的保护 xff08 进栈指令 xff09 保护程序的断点 包含了两部分内容
  • 深度学习理论(李宏毅

    2022 再探宝可梦 数码宝贝分类器 浅谈机器学习原理 哔哩哔哩 bilibili more parameters easier to overfit why 但是怎么定这个有未知数的function呢 那通常假设你没有什么想法的话 往往你
  • CNN (吴恩达 2021

    week1 2 02 边缘检测例子 哔哩哔哩 bilibili 我们之前在说面部识别介绍过 xff0c 要识别面部 xff0c 都是从细微的边缘入手 xff0c 一层一层聚类 xff0c 最终实现人脸的识别 神经网络由浅层到深层 xff0c
  • Transformer(李宏毅2022)

    本讲内容 xff1a Seq2seq model xff0c 以Transformer模型为例 xff08 Encoder Decoder架构 xff09 应用 xff1a 语音辨识 语音翻译 语音合成 聊天机器人 NLP 文法剖析 mul
  • 【安全测试学习】基于bWAPP靶场,使用sqlmap实现脱库实战

    以上仅是个人学习安全测试整理 xff0c 如用于其它用途责任自负 xff01
  • 自监督模型 Self-supervised learning(李宏毅2022

    这个红色的怪物叫做ELMo 最早的self supervised learning model 作业四的模型也是个transformer xff0c 只有0 1个million 最早的是ELMo Cookie Monster等你来凑 x1f
  • 2021 神经网络压缩 (李宏毅

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