美文网首页
验证Hinton的Dark Knowledge压缩模型

验证Hinton的Dark Knowledge压缩模型

作者: IcicleF | 来源:发表于2018-08-20 21:59 被阅读0次

Geoffrey Hinton在2015年写了一篇文章:

Hinton, G., Vinyals, O., & Dean, J. (2015). Distilling the knowledge in a neural network.

简介

这篇文章讲的是dark knowledge的应用,有两个:模型压缩特殊网络的学习

模型压缩部分,讲了用soft target训练小模型,可以让小模型有媲美大模型的表现。

特殊网络(specialist network)部分没认真看,不讨论。

Dark Knowledge思想

假设有一个图片识别的网络,输入一只猫,那么“狗”这个输出的softmax值一定比“船”高很多。

这个信息就是所谓的dark knowledge(个人理解)。

softmax函数的定义:q(i) = exp(z(i) / T) / ∑(exp(z(j) / T))

T是温度参数,一般取T = 1,这时就相当于求这个输出节点的exp值在所有输出中占的比重。显然

  • T→+∞时,q(i)→1/N,其中N是输出节点的总数
  • T→+0时,q(i)→[i == argmax(z(j))]。

显然,T越大,输出就越“均匀”,这种变得均匀了的输出就叫做soft target。

所谓的hard target,就是[0 1 0 0]这种one-hot label。

而soft target,就是[0.1 0.89 0.09 1e-6]这种,例如这个target对应一张猫的图片,那么第一个值就可能是狗,第二个就是猫,第三个可能是马什么的,第四个可能是船。体现了这些东西之间的关联性。

hard target很常见了,那么怎么搞出soft target呢?显然不能人工去搞,但我们可以训练一个网络,取一个合适的T值,把模型的输出当成soft target。

我这次实现的是论文中的“simplest form of knowledge distillation”。

实操

为了方便,直接使用 https://www.tensorflow.org/tutorials/ 上面的MNIST示例代码中的网络结构,但是要用函数式layer的方式来写。

这是一个朴素的全连接网络,包含一个隐含层,效果还算可以。为了测试,我们先把隐含层的节点数从512个改为64个,看一下准确率,大概是96.3%~96.4%。保持示例代码中隐含层512个节点不变的话,准确率大概98.5%。

接下来我们用512节点的模型的输出当做soft target训练64节点的网络。

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

inputs = tf.keras.layers.Input(shape=(28, 28))
flat = tf.keras.layers.Flatten()(inputs)
conv = tf.keras.layers.Dense(512, activation=tf.nn.relu)(flat)
dr = tf.keras.layers.Dropout(0.2)(conv)
fin = tf.keras.layers.Dense(10)(dr)
outputs = tf.keras.layers.Softmax()(fin)

这个网络的outputs就是一个T = 1的softmax;为了获得soft target,再写两个layer:

soft = tf.keras.layers.Lambda(lambda x: x / 4)(fin)
soft_o = tf.keras.layers.Softmax()(soft)

这里我们取温度T = 4,这个数值应该还有优化的余地。

接下来训练网络,暴力拿到soft target:

model = tf.keras.Model(inputs, outputs)
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)

soft_model = tf.keras.Model(inputs, soft_o)
y_train_soft = soft_model.predict(x_train)

用soft target训练小模型,和上面基本一样:

conv_s = tf.keras.layers.Dense(64, activation=tf.nn.relu)(flat)
dr_s = tf.keras.layers.Dropout(0.2)(conv_s)
fin_s = tf.keras.layers.Dense(10)(dr_s)
outputs_s = tf.keras.layers.Softmax()(fin_s)

model_s = tf.keras.Model(inputs, outputs_s)
model_s.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

model_s.fit(x_train, y_train_soft, epochs=5)

检验小模型,又需要重新用hard target,因此再建立一个Model:

model_e = tf.keras.Model(inputs, outputs_s)
model_e.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

loss, acc = model_e.evaluate(x_test, y_test)

print(loss)
print(acc)

准确率提升到96.8%,可以说是验证了Hinton的结论。

相关文章

网友评论

      本文标题:验证Hinton的Dark Knowledge压缩模型

      本文链接:https://www.haomeiwen.com/subject/jldriftx.html