神经网络模型的搭建有什么原则?
的有关信息介绍如下:得看你是针对学术研究还是解决具体问题。
如果是解决具体的问题。
选用业界已经反复验证过的,优秀的模型和方法,例如resnet,densenet,batch normalization,u-net等。不要用学术界最新的论文来建模型。
如果是学术界,想要提出一种新的性能优异的模型结构。
首先得对深度学习有着深刻的理解。提出一个idea,搭建模型去验证自己的idea。你去看inceptionv1-4的论文,文中有很多作者当时提出的想法和观点,比如2个3x3代替5x5卷积,那是不是1x7和7x1的就能代替7x7剪卷积。batch norm为什么会被提出,为什么作者人认为参数需要归一化。
作者总是会靠自己的敏锐的洞察力(inception),扎实的数学功底(wgan-gp),极富创造力的思维(gan)来提出新的模型。
目前来说,谁都办没发告诉你“究竟该如何搭建一个好的模型”。要不然也不会有这么多模型被不断的提出,改进。
当前人工智能领域的先进技术层出不穷,诸如计算机视觉、自然语言处理、影像生成,深度神经网络等先进技术日新月异。然而,从计算能力、内存或能源消耗角度来看,这些新技术的成本可能令人望而却步,其中某些成本对于大多数硬件资源受限的用户来说,则完全负担不起。所以说,人工智能许多领域将对神经网络进行必要的修剪,在确保其性能的同时降低其运行成本。
这就是神经网络压缩的全部要点,在这一领域,有多种方法来实现神经网络的压缩,如量化、分解蒸馏等等,本文的重点在于阐述神经网络的剪枝。
神经网络剪枝旨在去除性能良好但花费大量资源的多余部分网络。尽管大型神经网络的学习能力有目共睹,但事实上,在训练过程结束后,并不是所有的神经网络全部有用,神经网络剪枝的想法便是在不影响网络性能的情况下去除这些无用的部分。
在这个研究领域,每年均有几十篇,甚至数百篇论文发布,众多的论文揭示了这一想法蕴含的复杂性。通过阅读这些文献,可以快速识别出神经网络的无用部分,并在训练前后去除它们,值得强调的是,并不是所有的修剪都可以提速神经网络,某些工作甚至会事倍功半。
本文在阅读原生神经剪枝论文的基础上,提出了解决神经网络修剪的解决方案,依次回答了三个这一领域中的核心问题:“应该对哪部分进行修剪?”、“如何判断哪些部分可以修剪?”以及“如何在不损害网络的情况下进行修剪?”。综上所述,本文将详细介绍神经网络剪枝的结构、剪枝准则和剪枝方法。
当涉及神经网络的成本时,参数的数目和FLOPS(每秒钟的浮点操作次数)是其中最广泛使用的指标之一。看到网络显示出天文数字的参数(对某些人来说会花费高达数十亿美元的成本),这的确令人生畏。通过直接删除参数,从而直观地减少参数数目,这一方法肯定有效。实际上,这一方法在多个文献中均有提及,修剪参数是文献中提到的应用最为广泛的示例,被视为处理剪枝时的默认框架。
直接修剪参数的方法有诸多优点。首先,它很简单,在参数张量内,将其权重值设为零,便可以实现对参数的修剪。在Pytorch深度学习框架中,可以轻松地访问到网络的所有参数,实现起来非常简单。尽管如此,修剪参数的最大优势是:它们是网络中最小、最基本的元素,因此,只要数量足够多,便可以在不影响性能的情况下,对它们进行大量修剪。这种精细修剪的粒度使得可以在非常精密的模式下实现剪枝,例如,可以对卷积内核内的参数进行修剪。由于剪枝权值根本不受任何约束条件的限制,而且是修剪网络的最好方法,因此将这种方式称为非结构化剪枝。
然而,这种方法的致命缺点是:大多数深度学习框架和硬件无法加速稀疏矩阵的计算,这意味着无论你为参数张量填充多少个零,都不会对实际训练成本产生实质的影响,仅仅是一种直接改变网络架构的方式进行剪枝,而不是对任何框架都放之四海而皆准的方法。
非结构化(左)和结构化(右)剪枝之间的区别:结构化剪枝会同时删除卷积过滤器和内核行,而不仅仅是修剪参数。从而使得中间特征映射的数目更少。
结构化剪枝专注于对更为庞大的结构进行修剪,比如修剪整个神经元,或者,在更现代的深度卷积网络中,直接修剪卷积过滤器。大型网络往往包含许多卷积层,每个层中包含数百或数千个过滤器,可以对卷积层过滤器进行细粒度的修剪。移除这种结构不仅使得深度神经网络的层结构更为稀疏,而且这样做还可以去除过滤器输出的特性映射。
由于减少了参数,这种网络不仅存储起来更为轻便,而且计算量也得以降低,生成更为便捷的中间表示,因此在运行时需要更少的内存。实际上,有时降低带宽比减少参数数目更有益。对于涉及大型图像的任务,如语义分割或对象检测,中间表示可能比网络本身更加消耗内存,出于这些原因,可以将过滤器修剪视为默认的结构化剪枝。
在应用结构化剪枝时,应注意以下几方面:首先,应考虑如何构建卷积层,对于Cin输入通道和Cout输出通道,卷积层由Cout过滤器构成,过滤器分别对Cin内核进行计算;每个过滤器均输出一个特征映射,每个输入通道为一个内核专用。基于这种架构,卷积网络为堆叠的多个卷积层,当对整个过滤器进行剪枝时,可以观察到对每一个过滤器剪枝的过程,随后输出特征映射,这一过程也会导致对后续层内核的修剪。这意味着,当修剪过滤器时,在第一次删除参数之后,实际删除的参数数量是最初认为要删除的参数数量的数倍。
下面来考虑一下这种特殊情况,当一不留神把所有卷积层都修剪掉之后(虽然卷积层被修剪掉了,但神经网络并没有被摧毁,这由神经网络的架构来决定),无法链接到前一层的输出,这也可以是神经网络的一种剪枝方式:修剪掉所有卷积层,实际上等于修剪掉了所有上一层的输出,所以只能连接到其他地方(如残余连接或并行通道)。
在对过滤器剪枝时,首先应该计算出实际参数的确切数量,再根据过滤器在神经网络架构中的分布,修剪相同数量的过滤器,如果实际参数的数量与修剪参数数量不同,结果将不具备可比性。
在进入下一个主题之前,需要提及的是:依然有少数工作集中于剪枝卷积内核、核内架构乃至是特定的参数结构。然而,这些架构需要用特殊的方法来实现(如非结构化剪枝)。此外,另一种方法是对每个核中的某个参数进行修剪,将卷积层转换为“移位层”,这可以通过一次移位操作和一次1×1卷积的组合来实现。
结构化剪枝的缺点:输入和输出维度的改变会引发某些偏差。
在决定了采用何种结构进行剪枝之后,下一个问题便会是:“现在,如何找出保留哪些部分,哪些部分需要修剪?”为了回答这个问题,通过对参数、过滤器或其他特性进行排序基础上,生成一个恰当的剪枝准则。
一个非常直观而又有效的准则是:修剪掉那些权重绝对值最小的参数。事实上,在权重衰减的约束条件下,那些对函数没有显著贡献的参数在训练期间,它们的幅度会不断减小。因此,那些权重比较小的参数便显得多余了。原理很简单,这一准则在当前神经网络的训练中被广泛使用,已成为该领域的主角。
尽管这个准则在非结构化剪枝的实现中显得微不足道,但大家更想知道如何将其应用于结构化剪枝。一种简单的方法是根据过滤器的范数(例如L1或L2)对过滤器进行排序。这种方法实现起来简单粗暴,即将多个参数封装在一起:例如,将卷积过滤器的偏差和批归一化参数封装到一起,将在并行层的过滤器输出融合起来,从而减少通道数目。
其中一种方法是:在无需计算所有参数的组合范数的前提下,为需要修剪的每一层的特征映射插入一个可学习的乘法因子,当它减少为零时,有效地删除负责这个通道的所有参数集,该方法可用于修剪权重幅度较小的参数。
权重大小剪枝准则并非唯一流行的准则,实际上,还有另一个重要准则,即梯度大小剪枝准则,也非常适用。根据上世纪80年代的一些基础理论,通过泰勒分解去消除参数对损失的影响,某些指标:如反向传播的梯度,可提供一个不错的判断方法,来确定在不损害网络的情况下可以修剪掉哪些参数。
在实际项目中,这一准则是这样实现的:首先计算出小批量训练数据的累积梯度,再根据这个梯度和每个参数对应权重之间的乘积进行修剪。
最后一个需要考虑的因素是,所选择的剪枝准则是否适用于网络的所有参数或过滤器,还是为每一层独立计算而设计。虽然神经网络全局剪枝可以生成更优的结果,但它会导致层垮塌。避免这个问题的简单方法是,当所使用的全局剪枝方法无法防止层垮塌时,就采用逐层的局部剪枝。
局部剪枝(左)和全局剪枝(右)的区别:局部剪枝对每一层分别进行剪枝,而全局剪枝同时将其应用于整个网络
在明确了剪枝结构和剪枝准则之后,剩下就是应该使用哪种方法来剪枝一个神经网络。这实际上是最令人困惑的话题,因为每一篇论文都会带来自己的独有的剪枝方法,以至于大家可能会对到底选用什么方法来实现神经网络的剪枝感到迷盲。
在这里,将以此为主题,对目前较为流行的神经网络剪枝方法作一个概述,着重强调训练过程中神经网络稀疏性的演变过程。
训练神经网络的基本框架是:训练、剪枝和微调,涉及1)训练网络2)按照剪枝结构和剪枝准则的要求,将需要修剪的参数设置为0(这些参数之后也无法恢复),3)添加附加的epochs训练网络,将学习率设为最低,使得神经网络有一个从剪枝引起的性能损失中恢复的机会。通常,最后两步可以迭代,每次迭代均加大修剪率。
具体剪枝方法如下:按照权重大小剪枝原则,在剪枝和微调之间进行5次迭代。实验表明,通过迭代可以明显提高训练性能,但代价是要花费额外的算力和训练时间。这个简单的框架是许多神经网络剪枝的基础,可以看作是训练神经网络的默认方法。
有一些方法对上述经典框架做了进一步的修改,在整个训练过程中,由于删除的权重越来越多,加速了迭代过程,从而从迭代的优势中获益,与此同时,删除整个微调过程。在各个epoch中,逐渐将可修剪的过滤器数目减少为0,不阻止神经网络继续学习和更新,以便让它们的权重在修剪后能重新增长,同时在训练中增强稀疏性。
最后,Renda等人的方法指出:在网络被修剪后进行重新再训练。与以最低学习率进行的微调不同,再训练采用与原先相同的学习率,因此称这种剪枝方法为“学习率重绕”。这种剪枝后再一次重新训练的方法,比微调网络的性能更优。
为了加快训练速度,避免微调,防止训练期间或训练后神经网络架构的任何改变,许多工作都集中在训练前的修剪上:斯摩棱斯基在网络初始化时便对网络进行修剪;OBD(Optimal Brain Damage)在对网络初始化剪枝时采用了多种近似,包括一个“极值”近似,即“假设在训练收敛后将执行参数删除”,这种方法并不多见;还有一些研究对这种方法生成掩码的能力提出了保留意见,神经网络随机生成的每一层的掩码具有相似的分布特性。
另一组研究剪枝和初始化之间关系的方法围绕着“彩票假说”展开。这一假设指出,“随机初始化的密集神经网络包含一个初始化的子网,当隔离训练时,它可以在训练相同次数迭代后匹配原始网络的测试精度”。项目实践中,在刚刚初始化时,便使用已经收敛的剪枝掩码。然而,对这一剪枝方法的有效性,还存在着诸多质疑,有些专家认为,利用特定掩码来训练模型的性能甚至可以优于用“胜券”假设下获得的性能。
经典的剪枝框架、彩票假说的学习率调整比较
上述方法均共享相同的底层主题:在稀疏性约束下的训练。这一原则以一系列稀疏训练方法为核心,它包括在训练分布变化的情况下,执行恒定的稀疏率并逐步调整。由Mocanu等人提出,它包括:
1)用一个随机掩码初始化网络,并对网络进行一定比例的修剪
2)在一个epoch内训练这个修剪过的网络
3)修剪一定数量较小的权值,4)再生相同数量的随机权值。
这种情况下,剪枝掩码是随机的,被逐步调整以瞄准最小的导入权值,同时在整个训练过程中强制执行稀疏性。各层或全局的稀疏性级别可以相同。
稀疏训练在训练过程中周期性期切割和增长不同的权重,经过调整后的权重与相关参数的掩码相关
还有一些方法侧重于在训练期间学习掩码修剪,而不是利用特定准则来修剪权重。在这一领域,比较流行的有以下两种方法:1)对网络或层分开进行掩码学习,2)通过辅助参数进行掩码学习。第一种方法中可以采用多种策略:尽可能多的修剪的每层的过滤器,在最大限度地提高精度的前提下,插入基于attention的层或使用强化学习。第二种方法将剪枝视为一个优化问题,它倾向于最小化网络的L0范数和监督损失。
由于L0是不可微的,有些方法主要围绕着使用辅助的惩罚参数来实现,在前向通路中,将辅助的惩罚参数乘以其相应的参数来规避这个问题。还有一些方法采用了一种类似于“二进制连接”的方法,即:在参数选择时,应用随机门的伯努利分布,这些参数p利用“直接估计器”或其他学习方法获取。
有许多方法应用各种惩罚来增加权重,使它们逐步收缩为0,而不是通过手动修剪连接或惩罚辅助参数。实际上,这一概念相当古老,因为权重衰减是衡量权重大小的一个基本标准。除了单独使用重量衰减之外,还有许多方法专门为执行稀疏性而设计了惩罚。当前,还有一些方法在权重衰减的基础之上应用不同的正则化,以期进一步增加稀疏性。
在最近的研究中,有多种方法采用了LASSO(最小绝对收缩并选择操作符)来修剪权重或组。某些其他的方法还采用了针对弱连接的惩罚,以加大保留参数和修剪参数之间的距离,使它们对性能的影响降为最小。经验表明,在整个训练过程中进行惩罚,可以逐步修剪参数,从而达到无缝剪枝的目的。
在神经网络的训练过程中,无须从头开始实现(重用论文作者提供的源代码),在某些现成框架上应用上述基本剪枝方法,实现上相对会更加容易一些。
Pytorch 为网络剪枝提供了多种高质量的特性,利用 Pytorch 所提供的工具,可以轻松地将掩码应用到网络上,在训练期间对该掩码进行维护,并允许在需要时轻松地恢复该掩码。 Pytorch 还提供了一些基本的剪枝方法,如全局或局部剪枝,无论是结构化的剪枝还是非结构化的剪枝,均能实现。结构化剪枝适用于任何维度的权值张量,可以对过滤器、内核行,甚至是内核内的某些行和列进行修剪。这些内置的基本方法还允许随机地或根据各种准则进行剪枝。
Tensorflow 的Keras库提供了一些基本的工具来修剪权重较低的参数,修剪的效率根据所有插入的零引入的冗余来度量,从而可以更好地压缩模型(它与量化很好地结合)。
Blalock等人研发了一个自定义库 ShrinkBench ,以帮助社区剪枝算法进行规范化。这个自定义的库基于 Pytorch框架 ,旨在使修剪方法的实现更加容易,同时对训练和测试条件规范化。它为不同的剪枝方法(如随机剪枝,权重大小剪枝或梯度大小剪枝),提供了不同的基准。
综上所述,可以看出
1)剪枝结构定义了通过剪枝操作可以获得哪种收益
2)剪枝准则基于多种理论和实际的结合
3)剪枝方法倾向于围绕在训练过程中引入稀疏性以协调性能和成本。
此外,尽管神经网络的基础工作可以追溯到上世纪80年代末,但是,目前神经网络剪枝是一个非常动态的领域,期待有新的基础理论和新的基本概念出现。
尽管目前该领域百花齐放,但仍有很大的探索和创新空间。每种剪枝方法都试图回答一个问题(“如何重建修剪后的权重?”“如何通过优化学习修剪掩码?”“如何释放已经剪去的权重……”),上述所有的研究指明了一个方向:贯穿整个训练过程中的稀疏性。同时,这一方向带出了许多新的问题,比如:“剪枝准则在还没有收敛的网络上有效吗?”, “如何判断是否剪枝选定的权重会有益于所有稀疏的训练?”
神经网络搭建一般都是些经验原则,最常见的就是深度优先原则,即优先调整模型深度。
卷积核一般不会用太大,常见是3*3的。1*1的卷积核用来改变特征通道数目。
VGG可以看作是标准的卷积网络,GoogleNet搞出inception结构,这都是14年的设计。
残差模块的虽然只用了一个简单的旁路连接,但是贡献很大,一方面使得可训练的网络层次大大增加,另一方面使得网络节点的连接更为丰富。之前神经网络的连接层次过于分明,这种结构比较容易编程实现,但是可能存在非常大的问题。
DenseNet在残差网络的基础上又向前进一步,使用了“稠密连接”的模块,使得神经网络模型的性能可能又整体上提高了一些。
计算机中的神经网络设计,还得向大自然学习。如果从借鉴生物神经网络的思路去考虑的话,目前计算机神经网络存在以下问题:
(1)神经元结构简单;
(2)连接可能过于规整;
(3)缺少记忆机制,缺少动态模拟反馈的过程等;
当然还有更多的问题,比如调参数 严重依赖梯度下降和反向传播。
参照另一个回答:神经网络的经典结构是怎么设计出来的? - 哈哈哈的回答 - 芝士回答
很多神经网络的搭建,确实是炼丹,没有什么道理可言。
其中,有一些神经网络的结构,有着比较明确、清晰的含义。
举个例子,残差收缩网络针对强噪数据的情况,在其结构中嵌入了软阈值化(小波降噪的常用步骤)。
在残差收缩网络中,软阈值化有着明确的物理意义,就是为了应对强噪声的情况。
链接中的“ConvNet Architectures”章节对题主的问题有过一些讲述。虽然googlenet、resnet等结构复杂一些,但是他们的主线网络(卷积网络中从输入到输出最远的路线)同样遵循这个规律。
实际上如果是cv领域中,应该了解四个基本网络模型再去动手,分别是AlexNet,VGG,Inception, Resnet 四大模型。AlexNet是经典模型,VGG在AlexNet加深了层数,那么你需要理解加深层数之后怎么解决训练问题(如梯度问题,收敛问题)。Inception想法则和VGG想法不一样,不考虑加深网络层数,而是增加网络宽度,那么你需要理解加大网络宽度后的Inception解决什么问题。而Resnet提出是为了加深网络深度,那么Resnet是如何加深的以及怎么解决梯度消失问题和收敛问题的。在cv领域梳理好这四大模型,基本就可以根据这些东西设计自己的网络模型了。
但是在NLP领域其实没有那么通用的网络结构,需要作者多读论文,了解别人这样设计网络结构的原因。根据这些经验再去设计网络模型。
1.在神经网络模型的深度和广度上,优先选择深度.也就是为什么叫深度学习不叫广度学习.
2.奥卡姆剃刀定律:无需必要,勿增实体.
是不是剩下的就是经验了吧,我猜的~
人工神经网络是对人类神经系统的一种模拟。尽管人类神经系统规模宏大、结构复杂、功能神奇,但其最基本的处理单元却只有神经元。人工神经系统的功能实际上是通过大量神经元的广泛互连,以规模宏伟的并行运算来实现的。
人工神经网络模型至少有几十种,其分类方法也有多种。例如,若按网络拓扑结构,可分为无反馈网络与有反馈网络;若按网络的学习方法,可分为有教师的学习网络和无教师的学习网络;若按网络的性能,可分为连续型网络与离散型网络,或分为确定性网络与随机型网络;若按突触连接的性质,可分为一阶线性关联网络与高阶非线性关联网络。
神经网络的构造大体上都采用如下的一些原则:
由一定数量的基本神经元分层联接;
每个神经元的输入、输出信号以及综合处理内容都比较简单;
网络的学习和知识存储体现在各神经元之间的联接强度上。
神经网络解决问题的能力与功效除了与网络结构有关外,在很大程度上取决于网络激活函数。
北京理工大学大数据搜索与挖掘实验室张华平主任研发的NLPIR大数据语义智能分析平台,它是根据中文数据挖掘的综合需求,融合了网络精准采集、自然语言理解、文本挖掘和语义搜索的研究成果,并针对互联网内容处理的全技术链条的共享开发平台。主要有精准采集、文档转化、新词发现、批量分词、语言统计、文本聚类、文本分类、摘要实体、智能过滤、情感分析、文档去重、全文检索、编码转换等十余项功能模块,平台提供了客户端工具,云服务与二次开发接口等多种产品使用形式。