参考链接:深入理解Softmax:从“Hard”到“Soft”的转变_softmax hardmax-优快云博客
Softmax函数的用途
机器学习分类任务中,softmax函数不仅将神经网络的输出转化为概率分布,而且能够处理多分类问题。
从Hard到Soft
Softmax由Soft和max组成,先来理解max:
在某些情况下,我们会直接选择输出结果中的最大值作为预测结果,此为Hard max。即选择结果中的最大值,忽略其他重要的信息。
eg.输出结果为[0.1,0.4,0.5],选择2(索引)作为分类结果,忽略了分类结果为1的可能性。因此这种方式在实际应用场景中不合适,会丢失潜在的有意义的信息。
import numpy as np
# 示例数据
outputs = np.array([0.1, 0.4, 0.5])
# Hard max选择
predicted_class = np.argmax(outputs)
print(predicted_class) # 输出:2,对应0.5
为了更好地反映各个类别的信息,我们引入Softmax函数。与Hard max不同的是,Softmax不仅关注最大值,还衡量其他类别的可能性。通过将输出层中每个值转化为一个概率分布。
Softmax的数学原理与实现
Softmax函数的核心部分是指数函数,公式如下:
其中是输出结果中的第i个值,通过指数函数的作用,我们可以放大较大的值,缩小较小的值,这样便可拉开不同类别的差距。
eg.给出示例数据[1.0,2.0,3.0],我们来看一下,使用指数函数和不适用指数函数的差别:
import numpy as np
# 示例数据
outputs = np.array([1.0, 2.0, 3.0])
# 计算 Softmax
exp_outputs = np.exp(outputs)
softmax_outputs = exp_outputs / np.sum(exp_outputs)
print(softmax_outputs)
# 输出:[0.09003057 0.24472847 0.66524096]
经过Softmax转换后,最大的值的概率大,最小的值的概率最小,且都在0-1之间,概率和为1
Softmax的数值稳定问题
虽然Softmax函数的设计非常巧妙,但其会出现数值稳定问题。当输入值过大时,经过指数函数的变换结果非常大,会导致数值溢出问题,使得计算结果不准确。
因此,在实际应用中,会找到输出结果中的最大值,让每个值减去这个最大值,再应用Softmax函数。不仅能够避免数值溢出,而且能提高计算的精度。
# 数值稳定的Softmax实现
outputs = np.array([1000, 1001, 1002]) # 示例数据
# 减去最大值
shifted_outputs = outputs - np.max(outputs)
exp_outputs = np.exp(shifted_outputs)
softmax_outputs = exp_outputs / np.sum(exp_outputs)
print(softmax_outputs)
# 输出:[0.09003057 0.24472847 0.66524096]
为什么Softmax使用指数函数?
为什么Softmax要使用指数函数?指数函数有以下特性,使其在Softmax中非常有效:
- 非负性:指数函数的输出恒正,避免计算结果出现负值,且输入为负,输出就越接近0
- 输入输出正相关:指数函数具有输入越大,输出就越大;输入越小,输出就越小。有利于区分不同类别,拉开差距。
- 比例缩放:当输入数据的差距较大时(一个数据特别大,其他数据特别小),指数函数会保留这种差距,而Softmax会选择较大数据对应的类别,类似Hard max,但仍保留对其他选项的考虑。
Softmax的数值计算效率
在实际应用中,Softmax函数的计算可以通过向量化实现高效计算,大多数深度学习框架(Pytorch,Tensorflow灯)都对其进行优化,使其能在复杂神经网络和大规模数据中高效运行。
以下是使用Pytorch进行Softmax计算的实例:
import torch
import torch.nn.functional as F
# 示例数据
outputs = torch.tensor([0.2, 0.3, 0.5])
# 使用PyTorch的Softmax函数
softmax_outputs = F.softmax(outputs, dim=0)
print(softmax_outputs)
# 输出:tensor([0.3006, 0.3322, 0.3672])
Softmax与交叉熵损失函数的关系
当我们使用Softmax函数作为输出层的激活函数时,通常与交叉熵损失函数配合使用,来优化模型。交叉熵损失函数通过衡量预测分布与目标分布的差异,指导模型的学习过程。
交叉熵损失函数(Cross-EntropyLoss)的数学表达式为:
表示真实的目标概率分布(通常用one-hot表示),
表示预测的概率分布
这种组合的妙处在于,Softmax的输出是概率分布,而交叉熵损失函数正是衡量两个概率分布的差异。这种配合使得梯度下降过程中的导数计算非常简单且高效,因为在这种组合下,导数的结果与Softmax输出非常相关,这使得反向传播的计算更为直接。(需了解梯度下降,导数计算,反向传播)
Softmax函数的局限性
虽然Softmax函数在多分类任务中广泛使用,但它也有一些局限。例如,在类别数量较大的情况下(Imagenet1k的1000算多吗?),Softmax的计算成本非常大。此时会采用近似方法,层次化Softmax或负采样来降低计算复杂度。
Softmax在处理类别不平衡问题时,也表现可能不佳。如果某些类别的图片数量明显少于其他类别,模型会倾向于预测常见类别。这时,需要对损失函数进行加权处理,或改用其他处理方法,如Focal Loss