NAS 与模型剪枝的原创想法集锦

最近在 NAS 和模型压缩方向上积攒了不少零散的想法,趁今天集中整理一下,方便后续挑选来做实验。

神经架构搜索(NAS)相关想法

搜索策略层面。 能否用最简单直接的方式优化概率分布,让每一步都以较大概率走向更好的点,无穷多步后收敛?这让我想到 MCMC 采样的思路。另一个方向是用贪心的思路搜索线性结构,不必一次性枚举所有可能。

可解释性驱动的 NAS。 想在可解释性目标下做 NAS,也就是把”网络结构本身是否可解释”作为搜索的评价维度之一。进一步地,能否把可解释性问题做成 image translation 的形式?还可以考虑对可解释性进行分层处理:先做高层语义上的可解释,再逐步细化到细节层面。另外,在不影响判别能力的前提下,生成一个尽量大的 mask,用这个 mask 来对分类网络进行解释,也值得一试。

引入 Attention 机制。 目前 NAS 搜索到的结构大多是各种卷积组合,容易丢失 long-range 信息,可以考虑在搜索空间中加入类似 attention 的机制。对应地,结合 attention 的思路来生成剪枝 mask,应该也是一个可行的方向。带有 attention 的 auto-encoder 结构据说效果也很好,值得调研。

渐进式替换 Block。 NAS 中可以采用类似 progressive GAN 的方式来逐步替换 block,而不是一次性确定整个结构。更进一步,把 block 当作 channel,用剪枝的方法来做 NAS,也就是说 NAS 和剪枝在这个视角下是统一的。

NAS 与生成器结合。 将 NAS 应用到 GAN 的生成器上,尽量让每个网络节点生成图像的不同部分,相当于让结构搜索本身也带上可解释性的味道。

无监督/弱监督场景。 将 NAS 应用到无监督或弱监督任务上,思路是让 AI 先做无监督学习找到内在规律,然后再进行标注,推进下一步训练。

从 dataset 角度来考虑 NAS。 目前大多数 NAS 工作针对固定数据集,从 dataset 本身的特性出发来指导架构搜索,是个值得探索的方向。

模型剪枝相关想法

基于统计的 channel 剪枝。 可以直接通过统计方法确定某个卷积层能删掉多少 channel,或者在训练过程中就对 channel 做类似排序的操作,按阈值剪掉。具体地,根据 weight 的统计特性进行剪枝:如下图所示,在中间划一条横线,根据横坐标的值来确定剪枝的相对比例。

基于冗余度的 channel 剪枝。 考虑 layer 的冗余程度:如果某层输出的 feature map 之间差异较小,说明部分 kernel 比较相似,可以去掉。可以取一个 batch 的数据来统计,或者直接对卷积核参数求二范数矩阵再取平均,最小的也就说明 kernel 之间比较相似、冗余较高。更进一步,可以将卷积核展开后计算相对夹角,作为相似度的衡量指标。

基于 feature map 稀疏性剪枝。 利用 feature map 上的稀疏项来剪枝,而不是卷积核上的稀疏项,思路上有所不同,值得对比实验。

渐进式剪枝。 将剪枝从”一次剪掉”改成慢慢 shift 的方式,效果应该会好很多。还可以在剪枝过程中,将卷积核慢慢转换为 depthwise 或 group conv 的形式,把结构简化和参数裁减结合起来。

剪枝的 EM 算法。 把剪枝问题套进 EM 框架来处理,E 步估计哪些 channel/kernel 冗余,M 步更新网络权重,循环迭代。

NAS 做快速剪枝。 既然可以对非结构化剪枝的 mask 求梯度,那对结构化剪枝同样也可以求梯度,然后整体排序,整个过程就相当于一个 NAS 的过程。

先训练大网络再剪枝重训。 尝试在训练时先训练更大的网络,然后剪枝后重新 fine-tune,这个流程验证一下效果。

逐层蒸馏构建小网络。 从下往上构建小网络,让小网络每一层的输出尽量与大网络相同,也就是逐层的 distillation。局部的知识蒸馏也值得尝试:很多复杂结构只是训练起来更容易,train 完之后可以考虑去掉这些辅助结构,再通过蒸馏迁移到更简单的结构上。

利用 EfficientNet 的思路确定剪枝比例。 利用 EfficientNet 的思路来找各层剪枝的相对比例(即相对冗余度),初始化为相同比例,然后根据性能进行调整。这个比例的确定可以用遗传算法,或者叫做”neural transform search for pruning”:不直接搜索确定结构,而是搜索一种转换模式(condition NAS),不用对每个条件都做一次完整搜索,只要搜到一组函数即可,相当于对这个过程进行松弛化。

动态网络与自适应推断

基于 skipnet 思路做动态 channel 选择。 skipnet 跳过某些 block,可以考虑做成跳过某些 channel,在剪枝上更进一步:根据激活值选取需要传递到下一层的 channel 数量,最终指标用整个数据集上的期望 inference 时间来衡量。对应地,也可以用对抗的思路来学习 skip 策略。

基于路径统计的动态网络。 根据前面的计算结果来决定是否走下一步,形成基于路径统计的动态推断机制。

仅凭内部神经元响应判断输入复杂度。 仅通过内部神经元的响应来判断输入的复杂程度,从而决定后面选取什么样的网络来处理。

级联小-大网络推断。 用前置小网络做预判断(poor locality),如果输出的 entropy 较大,再调用更大的网络处理。

Neural Decision Tree。 拿一批从小到大的 pretrain 模型,根据”能正确判断该样本的最小模型 index”来训练一个分类器,使其能自动根据输入找到最适合的模型。也可以用 REINFORCE 的方式来训练这个选择策略。

浅层分类器 + self-ensemble。 在网络浅层加一个分类器,用于确定在哪一层输出结果,loss 中鼓励尽可能在浅层输出且精度更高。顺便可以尝试 self-ensemble:将浅层分类器的输出用于后面层的加权。

利用 ReLU 做 channel sampler。 利用 relu 函数来剪枝:训练时相乘,inference 时索引,做成 channel sampler 的方式,并尝试对 MobileNet 进行加速,用空间换时间的方式来给网络加速。

其他相关想法

对抗学习获得 loss 和 w。 利用对抗学习来得到合适的 loss 和网络权重 w,具体形式还需要设计。

利用频率分解训练 auto-encoder。 利用频率分解的方式来训练 auto-encoder,将频域信息显式引入重建目标。

异构神经网络 ensemble。 异构神经网络的 ensemble,以及随机网络结构的实验,可以调研周志华的相关工作。

GAN 高频细节处理。 GAN 对高频细节处理不好,可以尝试将图片裁剪后放大到同一尺度 concat,再经过 1×1 conv 降维,相当于对局部信息进行放大处理,考虑设计这样的 block。

self-paced learning 与 curriculum learning。 先学习简单样本再学习困难样本,这个思路可以和上面的动态推断结合。

减小神经网络复杂度与奥卡姆剃刀。 从奥卡姆剃刀的角度来约束神经网络复杂度,作为正则化的理论出发点。

输出分布的量化友好性。 用加 loss 的方式让输出值的分布尽可能均匀或符合正态分布(entropy 最大的思路),方便后续量化;或者通过加一层类似 BN 的层来将分布转换为接近正态分布的形式。

神经网络哈希。 用神经网络做类似哈希的算法,将抽取的特征拿来比较两张图片之间的相似性。

按 StackGAN 方式 fine-tune。 按照 StackGAN 的方式来进行 fine-tune,分阶段逐步提升分辨率和细节。

hw 维度转置测试。 将 hw 维度上进行转置之后的图像 cat 到一起进行测试,看看能带来什么效果。

尝试不同数据集下的 channel 敏感度。 已经证明在不同初始化情况下 channel 敏感度分布是一样的,那么在不同数据集下呢?剪枝实验时同时将剪枝速度考虑进去。

阅读笔记:AutoML Survey

最近看了一篇 AutoML 综述——Taking the Human out of Learning Applications: A Survey on Automated Machine Learning

文章指出 NAS 已经被用在 Google 的 Cloud AutoML 中。自动化特征工程方面,已有工作包括 Data Science Machine(DSM)、ExploreKit 和 FeatureHub,甚至已经有商业产品 FeatureLabs 出现。DSM 关注数据集内部的关系,这个思路和从 dataset 角度来考虑 NAS 有一定共通之处。