You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Softmax交叉熵损失解析梯度与数值梯度不匹配问题

Softmax交叉熵损失梯度解析解与数值解不匹配问题排查

你实现的Softmax交叉熵损失梯度中,解析解与数值解差异显著,代码及运行结果如下:

原代码

import numpy as np

def softmax(z):
  expp = np.exp(z)
  
  return np.divide(expp, np.sum(expp))

def cost(z, y):
  s = softmax(z)
  
  return -np.sum(y * np.log(s)) / len(y)

def costprime(z, y):
  prime = []

  for i in range(len(z)):
    values = z.copy()

    values[i] += 1.0e-10

    prime.append((cost(values, y) - cost(z, y)) / 1.0e-10)

  return prime


z = np.array([1.1, 2.2, 0.3, -1.7])
y_expected = np.array([0, 0, 1, 0])

s = softmax(z)

cost_gradient = s - y_expected
numerical_derivative = costprime(z, y_expected)

print(cost_gradient)
print(numerical_derivative)

运行结果

[0.22151804  0.66547696 -0.90046553  0.01347053]

[0.05538014491435206, 0.16636914068612896, -0.2251154818111445, 0.0033673064336881]

问题原因

核心差异来自损失函数的平均操作:

  • 你的cost函数对交叉熵损失做了平均(除以len(y),此处len(y)=4),计算的是单样本平均损失。
  • 解析梯度公式s - y_expected是针对未做平均的总损失(所有样本损失之和)推导的结果,没有考虑平均操作带来的缩放因子。

观察数值解和解析解的比值:0.22151804 / 0.05538014 ≈4,正好等于len(y),验证了这一点。

解决方法

将解析梯度也除以len(y),匹配cost函数的平均逻辑:

修改解析梯度的计算代码:

cost_gradient = (s - y_expected) / len(y)

修改后重新运行,输出结果会与数值梯度高度匹配(微小差异是数值梯度的有限差分近似误差,属于正常现象):

[0.05537951 0.16636924 -0.22511638 0.00336763]
[0.05538014491435206, 0.16636914068612896, -0.2251154818111445, 0.0033673064336881]

内容的提问来源于stack exchange,提问作者Jawad Damir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:44:52