我有一个softmax层(只有激活本身,没有将输入乘以权重的线性部分,并且我想为此做一个后向传递。
我已经找到许多有关SO的教程/答案,但是它们似乎都使用X
作为(1, n_inputs)
向量。我想将其用作(n_samples, n_inputs)
数组,并且仍然要对前进/后退传递进行正确的矢量化实现。
我编写了以下前向传递,对每行/样本的输出进行了归一化(正确吗?):
import numpy as np
X = np.asarray([
[0.0, 0.0],
[0.0, 1.0],
[1.0, 0.0],
[1.0, 1.0]], dtype=np.float32)
def prop(self, X):
s = np.exp(X)
s = s.T / np.sum(s, axis=1)
return s.T
它为我提供正向传播(包括其他层)的最终结果为:
Y = np.asarray([
[0.5 , 0.5 ],
[0.87070241, 0.12929759],
[0.97738616, 0.02261384],
[0.99200957, 0.00799043]], dtype=np.float32))
因此,这是softmax的输出,如果正确的话。现在,我应该如何编写后退密码?
我已经得出softmax的导数为:
1)如果i=j
:p_i*(1 - p_j)
,
2)如果i!=j
:-p_i*p_j
,
我尝试将导数计算为:
ds = np.diag(Y.flatten()) - np.outer(Y, Y)
但是它导致8x8矩阵对于随后的反向传播没有意义...编写它的正确方法是什么?
我在编写softmax函数:Softmax derivative in NumPy approaches 0 (implementation)时发现此问题非常有用。希望对您有所帮助。