url: https://arxiv.org/abs/1503.02531
year: NIPS 2014


簡介
將大模型的泛化能力轉移到小模型的一種顯而易見的方法是使用由大模型產生的類概率作為訓練小模型的“軟目標”

其中, T(temperature, 蒸餾溫度), 通常設置為1的。使用較高的T值可以產生更軟的類別概率分布。 也就是, 較高的 T 值, 讓學生的概率分布可以更加的接近與老師的概率分布,
下面通過一個直觀的例子來感受下
def softmax_with_T(logits, temperature):
for t in temperature:
total = 0
prob = []
for logit in logits:
total += np.exp(logit/t)
for logit in logits:
prob.append(np.exp(logit/t) / total)
print('T={:<4d}'.format(t), end=' ')
for p in prob:
print('{:0.3f}'.format(p), end=' ')
print()

可以看出, softmax 輸出的項比例與 logits原始比例之間的關系與 logits 本身的模長以及 T 值大小相關, 感覺 T 值需要仔細調整下, 至少能反應 logits 之間的大致關系, 而且可以看出, softmax_with_T 受兩個變量的影響, 直接來比較的話, 比較難分析. 當 T 遠大於 logits 的模長時, softmax 的輸出尺度在相同的數量級下(如logits=[6,3,1], T=25), 這樣看的話, 即使老師和學生的 logit 相差很遠, 經過具有很大 T 的 softamx 之后, 數量級幾乎相同, 這樣是不合理的. 但是, 下面的公式推導結果加上實驗結果表明, 認真看梯度才是王道, 看輸出的話, 完全找不到感覺, 對於軟標簽交叉熵損失
梯度推導
\(e^x\)泰勒展開
\(T\rightarrow \infty\)時, \(\frac{Z_i}{T}\rightarrow 0\)
假設logits已經單獨進行了zero-center中心化處理,那么,
這樣的話, 當T值最夠大, 方法就變為求老師和學生的 logits 的 L2 距離了.
術語 | 說明 |
---|---|
\(q^{soft}\) | 老師模型的 softmax 輸出軟標簽 |
\(q^{hard}\) | 訓練集 one-hot 硬標簽 |
\(p^{soft}\) | 學生模型的 softmax 輸出軟標簽 |
\(p^{hard}\) | 學生模型的 softmax 輸出硬標簽(T=1) |
論文中發現通常給予硬標簽損失函數 \(\color{red}{可忽略不計的較低權重}\) 可以獲得最佳結果。 由於軟目標產生的梯度的大小為 \(\frac{1}{T^2}\),因此當使用硬目標和軟目標時,將它們乘以 \(T^2\) 是很重要的, 這確保軟硬標簽對梯度相對貢獻在一個數量級。
實驗結果

思考
軟標簽交叉熵函數與 KL 散度的聯系


上式中, 由於 p 為老師的預測結果, 模型蒸餾時候, 老師模型被凍結, 從梯度反傳來看, 軟標簽交叉熵函數 等價於 KL 散度.
對於我而言, 這篇論文相對於 Do Deep Nets Really Need to be Deep? 貢獻就在於, 將 L2距離 和 KL 散度統一到一個公式中了, 由於到 T 足夠大, KL 散度的梯度與 L2 距離的一樣. 這篇論文中其他部分沒有讀懂, 沒有看到其他想要的東西. 后面知識積累了有機會在看看有沒有新感受吧.
蒸餾入門的話, 推薦 Do Deep Nets Really Need to be Deep? 這篇論文. 從實驗分析來說, 各種分析都很到位, 分析的方式也是易讀的, 容易理解. 就工程效果來看, 實際上Distilling the Knowledge in a Neural Network 這篇論文有效時候, T一般都挺大的, 那么KL 散度的實際的效果就是 L2 距離, 不如直接用 L2 距離, 理解上簡單, 調節超參少, 效果也非常好.