2017-04-16 6 views
1

스탠포드 cs244n 클래스의 경우 assignment 1을 통과하려고합니다. 문제 1b는 Softmax 기능에 대한 최적화를 권장합니다. 나는 N 차원 벡터의 Softmax를 얻을 수있었습니다. 나는 또한 MxN 차원 행렬의 Softmax를 얻었으나 열을 통해 for 루프를 사용했습니다. 다음 코드를 가지고 있습니다 :다차원 행렬의 Softmax 확률을 벡터화하는 방법

def softmax(x): 
    orig_shape = x.shape 

    # Matrix 
    if len(x.shape) > 1: 
     softmax = np.zeros(orig_shape) 
     for i,col in enumerate(x): 
      softmax[i] = np.exp(col - np.max(col))/np.sum(np.exp(col - np.max(col))) 
    # Vector 
    else: 
     softmax = np.exp(x - np.max(x))/np.sum(np.exp(x - np.max(x))) 
    return softmax 

더 최적화 된 Matrix 구현을 구현할 수 있습니까?

답변

3

그 차원의 일반적인 수의 ndarrays 커버 -

exp_max = np.exp(x - np.max(x,axis=-1,keepdims=True)) 
out = exp_max/np.sum(exp_max,axis=-1,keepdims=True) 
+0

답변 해 주셔서 감사합니다. 과제를 방송 할 것을 제안했기 때문에 답변을 답장으로 표시했습니다. –

1

코드를 실행할 축 (axis=1)을 지정해야하는 np.apply_along_axis을 사용할 수 있습니다. 다음은 작업 예입니다 : 관련 ufuncsNumPy broadcasting를 사용

In [1]: import numpy as np 

In [2]: def softmax(x): 
    ...:  orig_shape = x.shape 
    ...: 
    ...:  # Matrix 
    ...:  if len(x.shape) > 1: 
    ...:   softmax = np.zeros(orig_shape) 
    ...:   for i,col in enumerate(x): 
    ...:    softmax[i] = np.exp(col - np.max(col))/np.sum(np.exp(col - np.max(col))) 
    ...:  # Vector 
    ...:  else: 
    ...:   softmax = np.exp(x - np.max(x))/np.sum(np.exp(x - np.max(x))) 
    ...:  return softmax 
    ...: 

In [3]: def softmax_vectorize(x): 
    ...:  return np.exp(x - np.max(x))/np.sum(np.exp(x - np.max(x))) 
    ...: 

In [4]: X = np.array([[1, 0, 0, 4, 5, 0, 7], 
    ...:   [1, 0, 0, 4, 5, 0, 7], 
    ...:   [1, 0, 0, 4, 5, 0, 7]]) 

In [5]: print softmax(X) 
[[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01] 
[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01] 
[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01]] 

In [6]: print np.apply_along_axis(softmax_vecorize, axis=1, arr=X) 
[[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01] 
[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01] 
[ 2.08239574e-03 7.66070581e-04 7.66070581e-04 4.18260365e-02 
    1.13694955e-01 7.66070581e-04 8.40098401e-01]] 
+0

와우이 그 일의 또 다른 흥미로운 방법입니다. 감사. –