我在学习神经网络并用Python实现它。我首先定义了一个Softmax函数,我遵循了这个问题的解决方案 Softmax function – python。以下是我的代码:
def softmax(A): """ Computes a softmax function. Input: A (N, k) ndarray. Returns: (N, k) ndarray. """ s = 0 e = np.exp(A) s = e / np.sum(e, axis =0) return s
我被提供了一段测试代码来检查softmax
函数是否正确。test_array
是测试数据,test_output
是softmax(test_array)
的正确输出。以下是测试代码:
# Test if your function works correctly.test_array = np.array([[0.101,0.202,0.303], [0.404,0.505,0.606]]) test_output = [[ 0.30028906, 0.33220277, 0.36750817], [ 0.30028906, 0.33220277, 0.36750817]]print(np.allclose(softmax(test_array),test_output))
然而,根据我定义的softmax
函数。使用softmax(test_array)
测试数据返回
print (softmax(test_array))[[ 0.42482427 0.42482427 0.42482427] [ 0.57517573 0.57517573 0.57517573]]
能有人指出我定义的softmax
函数的问题吗?
回答:
问题出在你的求和上。你在axis 0上求和,而你应该保持axis 0不变。
为了对同一个样本中的所有条目求和,即同一行,你应该使用axis 1。
def softmax(A): """ Computes a softmax function. Input: A (N, k) ndarray. Returns: (N, k) ndarray. """ e = np.exp(A) return e / np.sum(e, axis=1, keepdims=True)
使用keepdims
来保持形状,以便能够将e
除以总和。
在你的例子中,e
计算结果为:
[[ 1.10627664 1.22384801 1.35391446] [ 1.49780395 1.65698552 1.83308438]]
然后每个样本的总和(return
行中的分母)是:
[[ 3.68403911] [ 4.98787384]]
然后函数将每一行除以其总和,给出你test_output
中的结果。
正如MaxU指出的,在指数化之前去除最大值是一个好做法,以避免溢出:
e = np.exp(A - np.sum(A, axis=1, keepdims=True))