当前位置:   article > 正文

Distilling the Knowledge in a Neural Network_hinton g e,vinyals o,dean j.distilling the know-le

hinton g e,vinyals o,dean j.distilling the know-ledge in a neural network[j]

文章目录

Hinton G., Vinyals O. & Dean J. Distilling the Knowledge in a Neural Network. arXiv preprint arXiv 1503.02531

q 1 = exp ⁡ ( z i / T ) ∑ j exp ⁡ ( z j / T ) . q_1 = \frac{\exp(z_i/T)}{\sum_j \exp(z_j/T)}. q1=jexp(zj/T)exp(zi/T).

主要内容

这篇文章或许重点是在迁移学习上, 一个重点就是其认为soft labels (即概率向量)比hard target (one-hot向量)含有更多的信息. 比如, 数字模型判别数字 2 2 2 3 3 3 7 7 7的概率分别是0.1, 0.01, 这说明这个数字 2 2 2很有可能和 3 3 3长的比较像, 这是one-hot无法带来的信息.

于是乎, 现在的情况是:

  1. 以及有一个训练好的且往往效果比较好但是计量大的模型 t t t;

  2. 我们打算用一个小的模型 s s s去近似这个已有的模型;

  3. 策略是每个样本 x x x, 先根据 t ( x ) t(x) t(x)获得soft logits z ∈ R K z \in \mathbb{R}^K zRK, 其中 K K K是类别数, 且 z z z未经softmax.

  4. 最后我们希望根据下面的损失函数来训练 s s s:
    L ( x , y ) = T 2 ⋅ L s o f t ( x , y ) + λ ⋅ L h a r d ( x , y ) \mathcal{L(x, y)} = T^2 \cdot \mathcal{L}_{soft}(x, y) + \lambda \cdot\mathcal{L}_{hard}(x, y) L(x,y)=T2Lsoft(x,y)+λLhard(x,y)

其中
L s o f t ( x , y ) = − ∑ i = 1 K p i ( x ) log ⁡ q i ( x ) = − ∑ i = 1 K exp ⁡ ( v i ( x ) / T ) ∑ j exp ⁡ ( v j ( x ) / T ) log ⁡ exp ⁡ ( z i ( x ) / T ) ∑ j exp ⁡ ( z j ( x ) / T ) \mathcal{L}_{soft}(x, y) = -\sum_{i=1}^K p_i(x) \log q_i (x) = -\sum_{i=1}^K \frac{\exp(v_i(x)/T)}{\sum_j \exp(v_j(x)/T)} \log \frac{\exp(z_i(x)/T)}{\sum_j \exp(z_j(x)/T)} Lsoft(x,y)=i=1Kpi(x)logqi(x)=i=1Kjexp(vj(x)/T)exp(vi(x)/T)logjexp(zj(x)/T)exp(zi(x)/T)

L h a r d ( x , y ) = − log ⁡ exp ⁡ ( z y ( x ) ) ∑ j exp ⁡ ( z j ( x ) ) \mathcal{L}_{hard}(x, y) = -\log \frac{\exp(z_y(x))}{\sum_j \exp(z_j(x))} Lhard(x,y)=logjexp(zj(x))exp(zy(x))

至于 T 2 T^2 T2是怎么来的, 这是为了配平梯度的magnitude.

∂ L s o f t ∂ z k = − ∑ i = 1 K p i q i ∂ q i ∂ z k = − 1 T p k − ∑ i = 1 K p i q i ⋅ ( − 1 T q i q k ) = − 1 T ( p k − ∑ i = 1 K p i q k ) = 1 T ( q k − p k ) = 1 T ( e z i / T ∑ j e z j / T − e v i / T ∑ j e v j / T ) .

Lsoftzk=i=1Kpiqiqizk=1Tpki=1Kpiqi(1Tqiqk)=1T(pki=1Kpiqk)=1T(qkpk)=1T(ezi/Tjezj/Tevi/Tjevj/T).
zkLsoft=i=1Kqipizkqi=T1pki=1Kqipi(T1qiqk)=T1(pki=1Kpiqk)=T1(qkpk)=T1(jezj/Tezi/Tjevj/Tevi/T).
T T T足够大的时候, 并假设 ∑ j z j = 0 = ∑ j v j = 0 \sum_j z_j=0 = \sum_j v_j =0 jzj=0=jvj=0, 有
∂ L s o f t ∂ z k ≈ 1 K T 2 ( z k − v k ) . \frac{\partial \mathcal{L}_{soft}}{\partial z_k} \approx \frac{1}{KT^2} (z_k - v_k). zkLsoftKT21(zkvk).
故需要加个 T 2 T^2 T2取抵消这部分的影响.

代码

其实一直很好奇的一点是这部分代码在pytorch里是怎么实现的, 毕竟pytorch里的交叉熵是
− log ⁡ p y ( x ) -\log p_y(x) logpy(x)

另外很恶心的一点是, 我看大家都用的是 KLDivLOSS, 但是其实现居然是:
L ( x , y ) = y ⋅ log ⁡ y − y ⋅ x , \mathcal{L}(x, y) = y \cdot \log y - y \cdot x, L(x,y)=ylogyyx,
注: 这里的 ⋅ \cdot 是逐项的.

def kl_div(x, y):
    return y * (torch.log(y) - x)


x = torch.randn(2, 3)
y = torch.randn(2, 3).abs() + 1

loss1 = F.kl_div(x, y, reduction="none")
loss2 = kl_div(x, y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这时, 出来的结果长这样

tensor([[-1.5965,  2.2040, -0.8753],
        [ 3.9795,  0.0910,  1.0761]])
tensor([[-1.5965,  2.2040, -0.8753],
        [ 3.9795,  0.0910,  1.0761]])
  • 1
  • 2
  • 3
  • 4

又或者:

def kl_div(x, y):
    return (y * (torch.log(y) - x)).sum(dim=1).mean()


torch.manual_seed(10086)

x = torch.randn(2, 3)
y = torch.randn(2, 3).abs() + 1

loss1 = F.kl_div(x, y, reduction="batchmean")
loss2 = kl_div(x, y)

print(loss1)
print(loss2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
tensor(2.4394)
tensor(2.4394)
  • 1
  • 2

所以如果真要弄, 应该要

def soft_loss(z, v, T=10.):
    # z: logits
    # v: targets
    z = F.log_softmax(z / T, dim=1)
    v = F.softmax(v / T, dim=1)
    return F.kl_div(z, v, reduction="batchmean")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/731795
推荐阅读
相关标签
  

闽ICP备14008679号