不愧商汤,一面巨深入。。

2024-01-11 18:19:12 浏览数 (2)

给大家看一个商汤一面的内容~

你说简单不?

看起来不难,其实过程来说,肯定不会很简单,只围绕一个问题展开!

趁这个机会。咱们今天也和大家一起来聊聊,softmax的各个知识点,以及注意点。

有同学想要下期出二面以及三面内容的,可以评论区留言。。

关于softmax

咱们就从softmax的简单介绍以及更多的细节来介绍一下。

大家查漏补缺,感觉有用可以慢慢看~

基础知识点

Softmax函数主要用于多类别分类问题中,它通过对原始的类别分数进行转换,将它们转化为概率分布。这个过程使得模型的输出更容易解释为各个类别的概率。

接下来具体说说Softmax函数的计算过程:

给定一个具有 k 个类别的输入向量

z = (z_1, z_2, ..., z_k)

,Softmax函数的计算步骤如下:

  1. 计算每个类别的未归一化分数(logit):
s_i = e^{z_i}
  1. 计算所有类别的未归一化分数之和:
S = sum_{j=1}^{k} s_j
  1. 计算每个类别的概率分布:
y_i = frac{e^{z_i}}{S}

这样,得到的输出向量

y = (y_1, y_2, ..., y_k)

中的每个元素都是对应类别的概率。这些概率的和为1,因此可以看作是一个有效的概率分布。

Softmax函数的优点之一是它对输入的敏感性。较大的输入相对应的类别概率会更接近1,而较小的输入对应的概率会接近0。这使得模型更加自信地预测最可能的类别。

在神经网络中,Softmax通常用于输出层,与交叉熵损失一起,构成一个端到端的多类别分类模型。在训练过程中,通过反向传播和梯度下降等优化算法来调整网络参数,使得模型的预测更加准确。

手撸softmax

这里,咱们对Softmax的推理过程进行详细的描述。

1. 计算原始分数(logits): 输入模型的原始分数是一个向量,表示每个类别的得分。假设有

K

个类别,对于第

i

个类别,其原始分数为

z_i

2. 计算指数函数: 对每个原始分数应用指数函数,得到指数化的分数。这是Softmax函数中的

e^{z_i}

部分。

e^{z_i}

3. 计算指数化分数的和: 计算所有类别的指数化分数之和。

sum_{j=1}^{K}e^{z_j}

4. 计算Softmax概率: 对于每个类别

i

,Softmax概率由以下公式给出:

P(class_i) = frac{e^{z_i}}{sum_{j=1}^{K}e^{z_j}}

5. 概率归一化: 由于Softmax概率是指数函数的结果,它们总和为1,可以视为一个概率分布。

让我们用具体的例子来演示这个过程:

假设有三个类别的原始分数为

[2.0, 1.0, 0.1]

1. 计算指数函数:

e^{2.0}, quad e^{1.0}, quad e^{0.1}

得到

[7.389, 2.718, 1.105]

2. 计算指数化分数的和:

7.389 2.718 1.105 = 11.212

3. 计算Softmax概率:

P(class_1) = frac{e^{2.0}}{11.212} approx 0.659
P(class_2) = frac{e^{1.0}}{11.212} approx 0.243
P(class_3) = frac{e^{0.1}}{11.212} approx 0.098

这样,我们得到了Softmax概率分布。

在下面代码示例中,可以看到 softmax 函数执行了这个过程,最终返回概率分布。

代码语言:javascript复制
import numpy as np

def softmax(logits):
    exp_logits = np.exp(logits)
    probabilities = exp_logits / np.sum(exp_logits)
    return probabilities

logits_example = np.array([2.0, 1.0, 0.1])

# 1: 计算指数函数
exp_logits = np.exp(logits_example)
print("指数函数结果:", exp_logits)

# 2: 计算指数化分数的和
sum_exp_logits = np.sum(exp_logits)
print("指数化分数的和:", sum_exp_logits)

# 3: 计算Softmax概率
softmax_probabilities = exp_logits / sum_exp_logits
print("Softmax概率:", softmax_probabilities)

首先咱们计算了原始分数的指数函数;

然后计算了指数化分数的和;

最后,通过除以这个和,得到了Softmax概率。

之后,大家自己执行上述代码,会得到以下输出:

代码语言:javascript复制
指数函数结果: [7.3890561  2.71828183 1.10517092]
指数化分数的和: 11.212508856732
Softmax概率: [0.65900114 0.24243297 0.09856589]

最后,这表明,对于给定的原始分数,Softmax概率分别为约0.659、0.242和0.099。这三个概率之和为1,符合概率分布的性质。

整个的代码复现了Softmax的推理过程,从原始分数到最终的概率分布。

代码语言:javascript复制
import numpy as np
import matplotlib.pyplot as plt

def softmax(logits):
    exp_logits = np.exp(logits)
    probabilities = exp_logits / np.sum(exp_logits)
    return probabilities

def plot_softmax_inference(logits, labels):
    probabilities = softmax(logits)
    
    # Plot logits
    plt.figure(figsize=(10, 5))
    plt.subplot(1, 2, 1)
    plt.bar(labels, logits, color='blue')
    plt.title('Logits')
    
    # Plot Softmax probabilities
    plt.subplot(1, 2, 2)
    plt.bar(labels, probabilities, color='green')
    plt.title('Softmax Probabilities')
    
    plt.show()

# Example logits and class labels
logits_example = np.array([2.0, 1.0, 0.1])
class_labels = ['Class A', 'Class B', 'Class C']

# Plot Softmax inference
plot_softmax_inference(logits_example, class_labels)

这段代码中,plot_softmax_inference 函数接受原始分数和类别标签.

然后绘制了两个子图:左侧子图显示原始分数,右侧子图显示经过Softmax处理后的概率分布。

Softmax运算上下溢问题

Softmax函数在计算时可能面临上溢(overflow)和下溢(underflow)的问题,这可能导致数值不稳定性,尤其是当输入的原始分数很大或很小时。为了解决这些问题,可以使用以下常见的技巧:

1. 减去最大值(Max Trick): 在计算Softmax概率时,对每个原始分数减去输入中的最大值。这可以防止指数函数的输入变得太大,从而减小了上溢的风险。

代码语言:javascript复制
def softmax(logits):
    max_logit = np.max(logits)
    exp_logits = np.exp(logits - max_logit)
    probabilities = exp_logits / np.sum(exp_logits)
    return probabilities

2. 使用稳定的Softmax: 使用特殊设计的算法来避免上溢和下溢,例如scipy.special.softmax中提供的稳定Softmax。

代码语言:javascript复制
from scipy.special import softmax

probabilities = softmax(logits)

这个函数使用数值稳定的方法来计算Softmax概率,通常更适合处理数值溢出和下溢的情况。

选择其中一种方法取决于你的需求和实际情况。通常情况下,减去最大值是一个简单而有效的方法。如果你在使用科学计算库,也可以考虑使用库中提供的稳定Softmax实现。

好了,今天的内容先这样,继续想看解决什么问题,评论区留言~

都到这里了,点赞~

0 人点赞