如何用数学和代码实现交叉熵损失函数?
摘要:交叉熵损失函数 这样吗? i=0 ——> n P_i = [3.0,1.0,−1.0] softmax(P_i) = [0.88, 0.12, 0.00] p_i = [1,0,0] L = -(p_i *- soft
交叉熵损失函数
这样吗?
i=0 ——> n
P_i = [3.0,1.0,−1.0]
softmax(P_i) = [0.88, 0.12, 0.00]
p_i = [1,0,0]
L = -(p_i *- softmax(P_i)) 【ennn,,这边怎么同时表示+和乘的操作,张量计算吗?】
--
你的理解还是有混淆,不过很接近了!让我纠正一下,并用清晰的方式表示。
正确的步骤:
1. 定义变量
原始输出(logits):z = [3.0, 1.0, -1.0]
真实标签的 one-hot:y = [1, 0, 0](假设真实类别是猫)
2. 计算 softmax
这是对原始输出 z 做的:
\[\text{softmax}(z)_i = \frac{e^{z_i}}{\sum_{j} e^{z_j}}
\]
所以:
\[p = \text{softmax}(z) = [0.88, 0.12, 0.00]
\]
这里 p 就是预测概率分布。
3. 计算交叉熵损失
公式:
\[L = -\sum_{i=0}^{2} y_i \cdot \log(p_i)
\]
代入:
\[L = -(1 \cdot \log(0.88) + 0 \cdot \log(0.12) + 0 \cdot \log(0.00))
\]
\[L = -\log(0.88) \approx 0.13
\]
你写的问题:
你写的是:
L = -(p_i *- softmax(P_i))
这里有错误:
p_i 和 P_i 混用:通常我们用 z 表示原始输出,p 表示 softmax 后的概率
*- 写法不对,应该是乘法和加法
你的 p_i = [1,0,0] 应该是真实标签 y_i
正确的向量/张量计算表示(Python风格):
import numpy as np
# 原始输出
z = np.array([3.0, 1.0, -1.0])
# 真实标签 one-hot
y = np.array([1.0, 0.0, 0.0])
# softmax
def softmax(x):
exp_x = np.exp(x - np.max(x)) # 数值稳定
return exp_x / np.sum(exp_x)
p = softmax(z) # [0.88, 0.12, 0.00]
# 交叉熵损失
L = -np.sum(y * np.log(p)) # 这就是 y_i * log(p_i) 的和再取负
print(L) # 大约 0.13
关键点总结:
输入是 z(原始分数),不是 p
softmax 作用于 z,得到预测概率 p
交叉熵公式是:L = -Σ (y_i * log(p_i))
在代码中,y * np.log(p) 是逐元素相乘,然后 sum 加起来
所以更准确的写法是:
\[L = -\sum_{i} (y_i \cdot \log(\text{softmax}(z)_i))
\]
或者简洁写为:
\[L = -\sum y_i \log(p_i),\quad p_i = \frac{e^{z_i}}{\sum_j e^{z_j}}
\]
这样?
交叉熵损失函数计算思想: z=[3.0, 1.0, -1.0], y=[1.0, 0.0, 0.0], p=softmax(z)=[0.9, 0.1, 0.0], L=-ylog(p)=-1.0log(0.9)=0.1054
完全正确! ✅
你的理解现在完全准确了:
z = [3.0, 1.0, -1.0] # 模型原始输出
y = [1.0, 0.0, 0.0] # 真实标签(one-hot)
p = softmax(z) = [0.9, 0.1, 0.0] # 预测概率
L = -y * log(p) = -1.0 * log(0.9) ≈ 0.1054
几个要点总结:
softmax作用:把原始分数 z 变成概率 p
交叉熵本质:只关心真实类别的预测概率,取负对数
其他类别贡献为0:因为 y 中其他位置是 0,所以 0 * log(任何数) = 0
直观理解:
预测概率 p_true = 0.9 → 损失很小(0.1054)
如果预测概率 p_true = 0.1 → 损失很大(2.3026)
如果预测概率 p_true = 1.0 → 损失为 0(完美预测)
你现在的理解完全正确!这就是交叉熵损失在多分类任务中的核心思想。
