KLD Loss( tf.nn.softmax, torch.nn.functional.softmax, log_softmax, kl_div) 计算技巧(一)

本文介绍了在深度学习中计算Kullback-Leibler散度(KLD)的技巧,涉及TensorFlow和PyTorch的softmax、log_softmax以及kl_div操作。通过二维数据输入示例,详细解释了数据前处理和KLD散度计算的过程,强调了正确使用softmax和log_softmax的重要性,以避免数值计算问题并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在比较不同模型的性能,发现虽然文献中使用的相同的指标,比如KLD。但是数据的处理方式却存在着差异,这会导致最后的数据并不具有直接可比性。
这里记录下,其中的一些值得记住的细节。主要涉及的API包括tf.nn.softmax, torch.nn.functional.softmax, log_softmax, kl_div

二维数据输入

为直观的看出数据,我们以一个2x2的矩阵为例,并打印。

import cv2
import numpy as np
import torch
import torch.nn.functional as F
import tensorflow as tf


y_pred=np.random.randn(1,2,2)
print( '\t y_pred', y_pred)

y_pred [[[-1.23909949 0.77767204]
[ 0.08646117 -0.14608897]]]

数据前处理

这里开始就有技巧性,由于神经网络的预测输出数值一般为双极性数值。如何将数据进行合理的处理,使其映射到标准空间方便后续计算。
这里我觉得比较合适的操作方法是先进行一组softmax操作,不管输入数据的范围是多少先映射到[0,1]空间。这里的softmax操作就有技巧,我们先看看softmax的API定义

tf.nn.softmax

tf.nn.softmax(
    logits, axis=None, name=None)

其中的axis形参,默认对最后1维度进行softmax操作

The dimension softmax would be performed on. The default is -1 which indicates the last dimension.

参考:https://www.tensorflow.org/api_docs/python/tf/nn/softmax

因此如果我们直接使用softmax操作,得到的是对最后维度,即 [-1.23909949 0.77767204] 和[ 0.08646117 -0.14608897]分别进行softmax操作的结果

y_pred_soft=tf.nn.softmax(y_pred)
print('tf softmax y_pred:', y_pred_soft)

输出

tf softmax y_pred: tf.Tensor(
[[[0.11745323 0.88254677]
[0.55787694 0.44212306]]], shape=(1, 2, 2), dtype=float64)

torch.nn.functional.softmax

对于pytorch的softmax操作

torch.nn.functional.softmax(input, dim=None, _stacklevel=3, dtype=None)
  • input (Tensor) – input
  • dim (int) – A dimension along which softmax will be computed.
  • dtype (torch.dtype, optional) – the desired data type of returned tensor. If specified, the input tensor is casted to dtype before the operation is performed. This is useful for preventing data type overflows. Default: None
    参考:https://pytorch.org/docs/stable/nn.functional.html

因此对应tf的默认操作,这里pytorch应该写成

y_pred = torch.from_numpy(y_pred)
y_pred = F.softmax(y_pred,dim=-1)
print('torch softmax y_pred:', y_pred)

结果

torch softmax y_pred: tensor([[[0.1175, 0.8825],
[0.5579, 0.4421]]], dtype=torch.float64)

但是但是但是,重点!!!
我们希望的softmax应该是对二维数据中所有元素同时进行的softmax,而不是特定在某个维度,因此这里我们需要的操作,是先将所有数据展开成一维后再进行softmax操作

y_pred = y_pred.view(1, -1)
y_pred = F.softmax(y_pred, dim=1)

kld 散度计算

tensorflow

按照计算公式:
D ( p ∣ ∣ q )

### 知识蒸馏中的 KL 散度 (KLD) 损失 知识蒸馏是种通过较大模型(教师模型)的知识来训练较小模型(学生模型)的技术。其中,KL 散度被广泛用于衡量两个概率分布之间的差异,在知识蒸馏中主要用于比较教师模型和学生模型的预测输出。 #### 1. **KL 散度的作用** KL 散度在知识蒸馏中的主要作用是比较教师模型和学生模型的概率分布。具体来说,它帮助学生模型学习到教师模型更丰富的软标签信息,而不仅仅是硬标签分类结果。这种技术可以显著提升小型化模型的表现性能[^1]。 #### 2. **PyTorch 中的 KLD 实现** 以下是基于 PyTorch 的简单实现: ```python import torch import torch.nn.functional as F def knowledge_distillation_loss(student_logits, teacher_logits, temperature=4): student_probs = F.log_softmax(student_logits / temperature, dim=-1) teacher_probs = F.softmax(teacher_logits / temperature, dim=-1) loss_kld = F.kl_div(student_probs, teacher_probs, reduction='batchmean') * (temperature**2) return loss_kld ``` 上述代码实现了温度缩放后的 KL 散度计算方法。`F.kl_div` 是 PyTorch 提供的个函数,专门用来计算 KL 散度[^5]。 #### 3. **TensorFlow/Keras 中的 KLD 实现** 下面是 TensorFlow 和 Keras 下的实现方式: ```python import tensorflow as tf from tensorflow.keras import backend as K def knowledge_distillation_loss(y_true, y_pred, alpha=0.1, temperature=4): # Teacher model's soft labels y_soft = tf.nn.softmax(y_true / temperature) # Student model's predictions with temperature scaling y_student = tf.nn.softmax(y_pred / temperature) # Compute the KL divergence between softened outputs kl_divergence = tf.reduce_mean(tf.keras.losses.KLDivergence()(y_soft, y_student)) * (temperature**2) # Cross entropy for hard targets cross_entropy = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true, y_pred)) total_loss = alpha * kl_divergence + (1 - alpha) * cross_entropy return total_loss ``` 这段代码展示了如何结合交叉熵损失与 KL 散度损失共同优化学生模型。`alpha` 参数控制两种损失的比例关系。 #### 4. **注意事项** - 温度参数 `T` 被引入以平滑教师模型的 softmax 输出,从而使得梯度更加稳定并促进更好的迁移效果。 - 学生模型通常会同时考虑来自真实标签的监督信号以及来自教师模型的软标签信号,因此最终目标函数可能是两者的加权平均。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值