我实现了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)
我错了什么?
答案 0 :(得分: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,而不是整个。