@article{katharopoulos2018not,
title={Not All Samples Are Created Equal: Deep Learning with Importance Sampling},
author={Katharopoulos, Angelos and Fleuret, F},
journal={arXiv: Learning},
year={2018}}
概
本文提出一种删选合适样本的方法, 这种方法基于收敛速度的一个上界, 而并非完全基于gradient norm的方法, 使得计算比较简单, 容易实现.
主要内容
设
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)为输入输出对,
Ψ
(
⋅
;
θ
)
\Psi(\cdot;\theta)
Ψ(⋅;θ)代表网络,
L
(
⋅
,
⋅
)
\mathcal{L}(\cdot, \cdot)
L(⋅,⋅)为损失函数, 目标为
θ
∗
=
arg
min
θ
1
N
∑
i
=
1
N
L
(
Ψ
(
x
i
;
θ
)
,
y
i
)
,
(1)
\tag{1} \theta^* = \arg \min_{\theta} \frac{1}{N} \sum_{i=1}^N\mathcal{L}(\Psi(x_i;\theta),y_i),
θ∗=argθminN1i=1∑NL(Ψ(xi;θ),yi),(1)
其中
N
N
N是总的样本个数.
假设在第
t
t
t个epoch的时候, 样本(被选中)的概率分布为
p
1
t
,
…
,
p
N
t
p_1^t,\ldots,p_N^t
p1t,…,pNt, 以及梯度权重为
w
1
t
,
…
,
w
N
t
w_1^t, \ldots, w_N^t
w1t,…,wNt, 那么
P
(
I
t
=
i
)
=
p
i
t
P(I_t=i)=p_i^t
P(It=i)=pit且
θ
t
+
1
=
θ
t
−
η
w
I
t
∇
θ
t
L
(
Ψ
(
x
I
t
;
θ
t
)
,
y
I
t
)
,
(2)
\tag{2} \theta_{t+1}=\theta_t-\eta w_{I_t}\nabla_{\theta_t} \mathcal{L}(\Psi(x_{I_t};\theta_t),y_{I_t}),
θt+1=θt−ηwIt∇θtL(Ψ(xIt;θt),yIt),(2)
在一般SGD训练中
p
i
=
1
/
N
,
w
i
=
1
p_i=1/N,w_i=1
pi=1/N,wi=1.
定义
S
S
S为SGD的收敛速度为:
S
:
=
−
E
P
t
[
∥
θ
t
+
1
−
θ
∗
∥
2
2
−
∥
θ
t
−
θ
∗
∥
2
2
]
,
(3)
\tag{3} S :=-\mathbb{E}_{P_t}[\|\theta_{t+1}-\theta^*\|_2^2-\|\theta_t-\theta^*\|_2^2],
S:=−EPt[∥θt+1−θ∗∥22−∥θt−θ∗∥22],(3)
如果我们令
w
i
=
1
N
p
i
w_i=\frac{1}{Np_i}
wi=Npi1 则
定义
G
i
=
w
i
∇
θ
t
L
(
Ψ
(
x
i
;
θ
t
)
,
y
i
)
G_i=w_i\nabla_{\theta_t} \mathcal{L}(\Psi(x_{i};\theta_t),y_{i})
Gi=wi∇θtL(Ψ(xi;θt),yi)
我们自然希望
S
S
S能够越大越好, 此时即负项越小越好.
定义
G
^
i
≥
∥
∇
θ
t
L
(
Ψ
(
x
i
;
θ
t
)
,
y
i
)
∥
2
\hat{G}_i \ge \|\nabla_{\theta_t} \mathcal{L}(\Psi(x_{i};\theta_t),y_{i})\|_2
G^i≥∥∇θtL(Ψ(xi;θt),yi)∥2, 既然
(7)式我有点困惑,我觉得(7)式右端和最小化(6)式的负项(
T
r
(
V
P
t
[
G
I
t
]
)
+
∥
E
P
t
[
G
I
t
]
∥
2
2
\mathrm{Tr}(\mathbb{V}_{P_t}[G_{I_t}])+\|\mathbb{E}_{P_t}[G_{I_t}]\|_2^2
Tr(VPt[GIt])+∥EPt[GIt]∥22)是等价的.
于是有
最小化右端(通过拉格朗日乘子法)可得 p i ∝ G ^ i p_i \propto \hat{G}_i pi∝G^i, 所以现在我们只要找到一个 G ^ i \hat{G}_i G^i即可.
这个部分需要引入神经网络的反向梯度的公式, 之前有讲过,只是论文的符号不同, 这里不多赘诉了.
注意 ρ \rho ρ的计算是比较复杂的, 但是 p i ∝ G ^ i p_i \propto \hat{G}_i pi∝G^i, 所以我们只需要计算 ∥ ⋅ ∥ \|\cdot\| ∥⋅∥部分, 设此分布为 g g g.
另外, 在最开始的时候, 神经网络没有得到很好的训练, 权重大小相差无几, 这个时候是近似正态分布的, 所以作者考虑设计一个指标,来判断是否需要根据样本分布
g
g
g来挑选样本. 作者首先衡量
显然当这部分足够大的时候我们可以采用分布
g
g
g而非正态分布
u
u
u, 但是这个指标不易判断, 作者进步除以
T
r
(
V
u
[
G
i
]
)
\mathrm{Tr}(\mathbb{V}_u[G_i])
Tr(Vu[Gi]).
显然
τ
\tau
τ越大越好, 我们自然可以人为设置一个
τ
t
h
\tau_{th}
τth. 算法如下
最后, 个人认为这个算法能减少计算量主要是因为样本少了, 少在一开始用正态分布抽取了一部分, 所以…
“代码”
主要是 G ^ i \hat{G}_i G^i部分的计算, 因为涉及到中间变量的导数, 所以需要用到retain_grad().
"""
这里只是一个例子
"""
import torch
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.dense = nn.Sequential(
nn.Linear(10, 256),
nn.ReLU(),
nn.Linear(256, 10),
)
self.final = nn.ReLU()
def forward(self, x):
z = self.dense(x)
z.retain_grad()
out = self.final(z)
return out, z
if __name__ == "__main__":
net = Net()
criterion = nn.MSELoss()
x = torch.rand((2, 10))
y = torch.rand((2, 10))
out, z = net(x)
loss = criterion(out, y)
loss.backward()
print(z.grad) #这便是我们所需要的