Softmax熵损失的解析梯度与数值梯度不匹配

问题描述 投票:0回答:1

我正在尝试在Python中实现softmax熵损失的梯度。但是,我可以看到解析梯度与数值梯度不匹配。这是我的 Python 代码:

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]

它们看起来非常不同。然而,当我尝试更改 z 的值以查看它们对成本的影响时,我发现数值导数比解析导数 (cost_gradient) 更准确

python neural-network derivative softmax cross-entropy
1个回答
0
投票

您需要从 z 的其余部分中减去最大值以获得数值稳定性

expp = np.exp(z - np.max(z))
return expp / np.sum(expp)

由于 softmax 函数使用指数,您可以获得超出浮点表示容量的值。

通过减去数组中的最大值,可以消除这个问题,同时保持相对值。为了避免这些问题,我们可以在应用指数函数之前从所有元素中减去向量 z 的最大值。这个技巧确保所有输入值都移向零,防止溢出,同时保持分数之间正确的相对差异。

© www.soinside.com 2019 - 2024. All rights reserved.