概述
AttentiveNAS论文解读
- 代码链接:https://github.com/facebookresearch/AttentiveNAS
- 论文链接:https://arxiv.org/pdf/2011.09011.pdf
论文是CVPR2021上Facebook的一个工作。
论文摘要
NAS技术在设计既好又快的SOTA模型上表现出了巨大潜力。最近,两阶段的NAS,比如BigNAS,解耦了了模型训练和搜索并实现了搜索的高效性。两阶段的NAS需要在训练阶段中从搜索空间采样,这个过程会影响到最终搜索出来的模型精度。虽然均匀采样由于其便捷简单被广泛采用,但是它和帕累托前沿是无关的。而帕累托前沿是我们在搜索过程中更关注的部分,所以均匀采样容易失去了进一步提升模型精度的机会。在本工作中,我们提出了AttentiveNAS,聚焦于提升帕累托性能的采样。同时我们也提出了在训练过程中高效的判别帕累托模型的算法。我们可以在宽范围的FLOPs中同步获得大量模型且没有额外的重训练或后处理过程。我们寻找到的AttentiveNAS模型家族里,能够在ImageNet上实现77.3%到80.7%的top-1准确率,超越了当前sota的模型,包括BigNAS, Once-for-All networks和FBNetV3。我们同时在ImageNet上使用仅491MFLOPs的模型实现了80.1%的准确率。
贡献
- 提出了AttentiveNAS策略,即通过聚焦Pareto-best or worst front 的attentive采样来提升当前两阶段的NAS方法。
- 提出了两种方法来让对Pareto-best or worst front的采样更加高效。
- 搜索到的AttentiveNAS模型家族在ImageNet上的给定FLOPs束下,实现了state-of-art。
动机
论文提到所谓两阶段NAS就是第一阶段无约束训练一个超网,第二阶段就是训练完成后然后再根据资源约束搜索出一个目标超网。像之前提到的Once-for-All,BigNAS都是如此。在之前两阶段的过程中,优化在搜索空间所有子网的平均损失是一个很自然的选择,但是其不是专门为实现性能和资源约束之间的trade-off来设计的。在实践中,我们在搜索过程中更希望得到帕累托最优的子网来实现最好的trade-offs。
目前还没有相关的工作,即调整第一阶段无约束训练的目标来使得第二阶段能够找到更好的子网。一个出于直觉的方法就是在可能会形成帕累托最优集合的这些子网上投入更多的训练预算,用更多的数据和迭代次数来训练这些模型。在实践中证明了该方法能够提升DNN的表现。
但是,提升表现最差的模型可能和提升表现最好的模型一样重要。将这些帕累托最差的模型的表现提升,可能会提升更优画的权重共享图,使得所有的可训练的组件(比如channel和layers)都能在最终表现中贡献出最大潜能。此外,改善帕累托最差架构的理由类似于 hard example mining。通过把帕累托最差架构当作困难样本。它可以在架构空间中提供更多信息梯度和更好的探索,从而产生更好的性能。
方法
Pareto-aware采样
论文的核心方法就是在训练过程中,怎样采样到Pareto-best or worst front的模型来进行训练,作者探讨实践了一系列 Pareto-aware的采样策略。
在一阶段,传统的无约束预训练的优化问题形式是:
min
W
E
α
∈
A
[
L
(
W
α
;
D
t
r
n
)
]
+
γ
R
(
W
)
minlimits_{W}mathbb{E}_{alphain{mathcal{A}}}[mathcal{L}(W_{alpha};D^{trn})]+gammamathcal{R}(W)
WminEα∈A[L(Wα;Dtrn)]+γR(W)
W
W
W是网络中的共享权重,
W
α
W_{alpha}
Wα是子网架构
α
alpha
α范围下的权重,
R
(
W
)
mathcal{R}(W)
R(W)是正则化部分。例如BigNAS三明治法则的正则化部分包含了最大子网和最小子网的loss以及权重衰减。
而Pareto-aware的采样策略更关注帕累托最优或者最差,关注最优的方法叫Bestup,关注最差的方法叫Worstup。目标可以描述成以下形式:
min
W
E
π
(
τ
)
∑
π
(
α
∣
τ
)
[
γ
(
α
)
L
(
W
α
;
D
t
r
n
)
]
minlimits_{W}mathbb{E}_{pi(tau)}sum_{pi(alpha|tau)}[gamma(alpha)mathcal{L}(W_{alpha};D^{trn})]
WminEπ(τ)π(α∣τ)∑[γ(α)L(Wα;Dtrn)]
为了简便,丢掉了
R
(
W
)
mathcal{R}(W)
R(W)。
τ
tau
τ表示计算阈值,在论文中是FLOPs。
γ
(
α
)
gamma(alpha)
γ(α)当
α
alpha
α是帕累托最优(采用Bestup方法)或者最差子网(采用Worstup方法)等于1,其余等于0。
为了解决上述优化问题,可以采用n次蒙特卡洛采样来进行近似:
min
W
1
n
∑
τ
o
∼
π
(
τ
)
n
[
∑
α
i
∼
π
(
α
∣
τ
o
)
k
γ
(
α
i
)
L
(
W
α
i
;
D
t
r
n
)
]
minlimits_{W}frac{1}{n}sum_{tau_osimpi(tau)}^n[sum_{alpha_isimpi(alpha|tau_o)}^kgamma(alpha_i)mathcal{L}(W_{alpha_i};D^{trn})]
Wminn1τo∼π(τ)∑n[αi∼π(α∣τo)∑kγ(αi)L(Wαi;Dtrn)]
令
P
(
α
)
P(alpha)
P(α)表示对模型
α
alpha
α的性能估计。如果目标是帕累托最优架构,则令
γ
(
α
)
=
I
(
P
(
α
i
)
>
P
(
α
j
)
,
∀
j
≠
i
)
gamma(alpha)=mathbb{I}(P(alpha_i)>P(alpha_j),forall jne i)
γ(α)=I(P(αi)>P(αj),∀j=i),
I
(
⋅
)
mathbb{I}(cdot)
I(⋅)表示指示函数。如果目标是帕累托最差架构,就设置
γ
(
α
)
=
I
(
P
(
α
i
)
<
P
(
α
j
)
,
∀
j
≠
i
)
gamma(alpha)=mathbb{I}(P(alpha_i)<P(alpha_j),forall jne i)
γ(α)=I(P(αi)<P(αj),∀j=i)。
性能估计
关于 P ( α ) P(alpha) P(α),一个理想化的选择是利用模型在验证集上的损失来进行评估。但是这种方法计算代价太昂贵。论文提出了两种相对高效的方法:一个是用老方法,训练一个accuracy predictor,或者直接采用训练时的mini-batch losses。这两种方法都比较直观,论文中也通过一定的相关性分析来说明这两种方法的有效性。
训练-算法流程
根据上述Pareto-aware的采样策略,在训练过程中有两个主要步骤:
- 对FLOPs采样,得到当前的计算阈值 τ 0 tau_0 τ0。
- 根据当前的阈值 τ 0 tau_0 τ0,均匀采样k个子网。
- 如果是Bestup方法,就在k个子网里选最好的子网来进行训练,反之选最差的子网。
- 计算其他正则部分(比如三明治法则),然后反向传播更新参数。
- 回到1重复训练。
因为是要找帕累托模型,所以需要先给定一个FLOPs τ tau τ,每一个 τ tau τ都会有其帕累托模型。所以需要先对FLOPs进行采样,而FLOPs的分布由超网决定。文中用了一个简单的方法来估计FLOPs的分布:在整个搜索空间中均匀采样大量的模型,计算其每个模型的FLOPs来得到一个估计的分布。
在给出一个FLOPs
τ
tau
τ约束后,如何采样出满足约束的模型呢?如果直接在整个搜索空间中进行均匀采样,可能需要很长时间才能找够满足约束的模型。为了实现高效采样,文中把一个模型的各个维度的参数解耦。一个模型可以表示为
α
=
[
o
1
,
.
.
.
,
o
d
]
∈
R
d
alpha=[o_1,...,o_d]in mathbb{R^d}
α=[o1,...,od]∈Rd,每一个
o
i
o_i
oi代表一个维度,比如channel width,kernel size等,令
τ
^
(
α
∣
τ
=
τ
)
hat{tau}(alpha|tau=tau)
τ^(α∣τ=τ)作为
τ
(
α
∣
τ
=
τ
)
tau(alpha|tau=tau)
τ(α∣τ=τ)的一个近似,则有
τ
^
(
α
∣
τ
=
τ
0
)
∝
∏
i
π
^
(
o
i
∣
τ
=
τ
0
)
hat{tau}(alpha|tau=tau_0)propto prod_ihat{pi}(o_i|tau=tau_0)
τ^(α∣τ=τ0)∝i∏π^(oi∣τ=τ0)
令
#
(
o
i
=
k
,
τ
=
τ
0
)
#(o_i=k,tau=tau_0)
#(oi=k,τ=τ0)为
(
o
i
=
k
,
τ
=
τ
0
)
(o_i=k,tau=tau_0)
(oi=k,τ=τ0)对在architecture-FLOPs采样池里的出现次数。我们就可以对上式右侧做如下近似:
π
^
(
o
i
=
k
∣
τ
0
)
=
#
(
o
i
=
k
,
τ
=
τ
0
)
#
(
τ
=
τ
0
)
hat{pi}(o_i=k|tau_0)=frac{#(o_i=k,tau=tau_0)}{#(tau=tau_0)}
π^(oi=k∣τ0)=#(τ=τ0)#(oi=k,τ=τ0)
对于算法流程中的k,文中测试了几种参数,分别设置成3,50,1000000。1000000这种情况是离线计算的,并使用acc predictor来进行预测。
另外,第二阶段搜索部分采用了HAT提到的进化算法,并不是文章重点。
实验结果
文章总结了一些实验中的现象。
- Worstup能够提升low-bound的帕累托表现。
- Worstup-1M一直都比Bestup-1M好,说明提升最差模型的性能反而比提升最好模型的性能更有用。
- 提升帕累托最差模型的表现能够提升帕累托最优模型的表现。
- Bestup方法在中等FLOPs下表现的相对更好。
- Worstup-3和Bestup-3都比Uniform好。
- 在通常情况下,Bestup-3算法表现的最好。
核心训练代码
# total subnets to be sampled
num_subnet_training = max(2, getattr(args, 'num_arch_training', 2))
optimizer.zero_grad()
### compute gradients using sandwich rule ###
# step 1 sample the largest network, apply regularization to only the largest network
drop_connect_only_last_two_stages = getattr(args, 'drop_connect_only_last_two_stages', True)
model.module.sample_max_subnet()#采样一个最大的子网
model.module.set_dropout_rate(args.dropout, args.drop_connect, drop_connect_only_last_two_stages) #dropout for supernet
output = model(images)
loss = criterion(output, target)
loss.backward()
with torch.no_grad():
soft_logits = output.clone().detach()#最大子网的输出用来做知识蒸馏
#step 2. sample the smallest network and several random networks
sandwich_rule = getattr(args, 'sandwich_rule', True)
model.module.set_dropout_rate(0, 0, drop_connect_only_last_two_stages) #reset dropout rate
for arch_id in range(1, num_subnet_training):#num_subnet_training>=2
if arch_id == num_subnet_training-1 and sandwich_rule:
model.module.sample_min_subnet()
else:
# attentive sampling with training loss as the surrogate performance metric
if arch_sampler is not None:
sampling_method = args.sampler.method
if sampling_method in ['bestup', 'worstup']:
target_flops = arch_sampler.sample_one_target_flops()#采样一个flops
candidate_archs = arch_sampler.sample_archs_according_to_flops(
target_flops, n_samples=args.sampler.num_trials
)#根据采样到的flops采样满足该flops的子网
my_pred_accs = []
for arch in candidate_archs:#计算每一个arch的mini-batch loss
model.module.set_active_subnet(**arch)
with torch.no_grad():
my_pred_accs.append(-1.0 * criterion(model(images), target))
if sampling_method == 'bestup':#选择最高精度
idx, _ = max(enumerate(my_pred_accs), key=operator.itemgetter(1))
else:#选择最低精度的模型
idx, _ = min(enumerate(my_pred_accs), key=operator.itemgetter(1))
model.module.set_active_subnet(**candidate_archs[idx]) #reset 继续设置到model里
else:
raise NotImplementedError
else:
model.module.sample_active_subnet()
# calcualting loss
output = model(images)
if soft_criterion:#如果使用知识蒸馏,就用最大子网蒸馏其他子网
loss = soft_criterion(output, soft_logits)
else:
assert not args.inplace_distill
loss = criterion(output, target)
loss.backward()
#clip gradients if specfied
if getattr(args, 'grad_clip_value', None):
torch.nn.utils.clip_grad_value_(model.parameters(), args.grad_clip_value)
optimizer.step()
最后
以上就是机灵悟空为你收集整理的AttentiveNAS论文解读AttentiveNAS论文解读的全部内容,希望文章能够帮你解决AttentiveNAS论文解读AttentiveNAS论文解读所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复