【问题标题】:Numerical computation of softmax cross entropy gradientsoftmax交叉熵梯度的数值计算
【发布时间】:2018-06-12 10:18:41
【问题描述】:

我实现了softmax()函数softmax_crossentropy()和softmax交叉熵的导数:grad_softmax_crossentropy()。现在我想用数值计算softmax交叉熵函数的导数。我试图通过使用有限差分法来做到这一点,但该函数只返回零。这是我的一些随机数据的代码:

import numpy as np

batch_size = 3
classes = 10

# random preactivations
a = np.random.randint(1,100,(batch_size,classes))
# random labels
y = np.random.randint(0,np.size(a,axis=1),(batch_size,1))

def softmax(a):
    epowa = np.exp(a-np.max(a,axis=1,keepdims=True))
    return epowa/np.sum(epowa,axis=1,keepdims=True)

print(softmax(a))

def softmax_crossentropy(a, y):
    y_one_hot = np.eye(classes)[y[:,0]]
    return -np.sum(y_one_hot*np.log(softmax(a)),axis=1)

print(softmax_crossentropy(a, y))

def grad_softmax_crossentropy(a, y):
    y_one_hot = np.eye(classes)[y[:,0]]
    return softmax(a) - y_one_hot

print(grad_softmax_crossentropy(a, y))

# Finite difference approach to compute grad_softmax_crossentropy()
eps = 1e-5
print((softmax_crossentropy(a+eps,y)-softmax_crossentropy(a,y))/eps)

我做错了什么?

【问题讨论】:

标签: python numpy softmax


【解决方案1】:

您可以这样做。我认为您指的是由 y 的指示矩阵指示的激活的梯度。

首先,我将a 实例化为float 以更改单个项目。

a = np.random.randint(1,100,(batch_size,classes)).astype("float")

那么,

np.diag(grad_softmax_crossentropy(a, y)[:, y.flatten()])

array([ -1.00000000e+00,  -1.00000000e+00,  -4.28339542e-04])

还有

b = a.copy()
for i, o in zip(y.max(axis=1), range(y.shape[0])):
    b[o, i] += eps

(softmax_crossentropy(b,y)-softmax_crossentropy(a,y))/eps
[ -1.00000000e+00  -1.00000000e+00  -4.28125536e-04]

所以基本上你必须在 softmax 中改变 a_i,而不是整个 a。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-22
    • 2017-10-22
    • 1970-01-01
    • 2021-05-29
    • 2017-07-20
    • 1970-01-01
    • 2016-07-16
    • 2017-05-30
    相关资源
    最近更新 更多