2017-08-29 81 views
1

我試圖實現softmax函數(Softmax的雅可比矩陣)的導數矩陣。在Python中從頭開始計算雅可比矩陣

我數學知道使用SoftMax(XI)的衍生物相對於X 1是:

enter image description here

其中紅色增量是Kronecker符號。

到目前爲止,我所實行的是:

def softmax_grad(s): 
    # input s is softmax value of the original input x. Its shape is (1,n) 
    # e.i. s = np.array([0.3,0.7]), x = np.array([0,1]) 

    # make the matrix whose size is n^2. 
    jacobian_m = np.diag(s) 

    for i in range(len(jacobian_m)): 
     for j in range(len(jacobian_m)): 
      if i == j: 
       jacobian_m[i][j] = s[i] * (1-s[i]) 
      else: 
       jacobian_m[i][j] = -s[i]*s[j] 
    return jacobian_m 

當我測試:

In [95]: x 
Out[95]: array([1, 2]) 

In [96]: softmax(x) 
Out[96]: array([ 0.26894142, 0.73105858]) 

In [97]: softmax_grad(softmax(x)) 
Out[97]: 
array([[ 0.19661193, -0.19661193], 
     [-0.19661193, 0.19661193]]) 

你們如何實現雅可比?我想知道是否有更好的方法來做到這一點。任何參考網站/教程也將不勝感激。

回答

2

您可以如下矢量化softmax_grad;

soft_max = softmax(x) 
​ 
# reshape softmax to 2d so np.dot gives matrix multiplication 
def softmax_grad(softmax): 
    s = softmax.reshape(-1,1) 
    return np.diagflat(s) - np.dot(s, s.T) 

softmax_grad(soft_max) 

#array([[ 0.19661193, -0.19661193], 
#  [-0.19661193, 0.19661193]]) 

詳細sigma(j) * delta(ij)sigma(j)您可以與np.diagflat(s)創建爲對角線元素的對角矩陣; sigma(j) * sigma(i)是可以使用np.dot計算的softmax的矩陣乘法(或外積):

0

我一直在糾正這一點,這就是我想到的。也許你會發現它很有用。我認爲它比Psidom提供的解決方案更加明確。

def softmax_grad(probs): 
    n_elements = probs.shape[0] 
    jacobian = probs[:, np.newaxis] * (np.eye(n_elements) - probs[np.newaxis, :]) 
    return jacobian