따라서 이것은 실제로 desertnaut의 답변에 대한 의견이지만 내 평판으로 인해 아직 댓글을 달 수 없습니다. 그가 지적했듯이 입력이 단일 샘플로 구성된 경우에만 버전이 정확합니다. 입력 값이 여러 샘플로 구성되어 있으면 잘못되었습니다. 그러나 desertnaut의 솔루션도 잘못되었습니다. 문제는 일단 1 차원 입력을받은 다음 2 차원 입력을 받는다는 것입니다. 이것을 당신에게 보여 드리겠습니다.
import numpy as np
# your solution:
def your_softmax(x):
"""Compute softmax values for each sets of scores in x."""
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum()
# desertnaut solution (copied from his answer):
def desertnaut_softmax(x):
"""Compute softmax values for each sets of scores in x."""
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum(axis=0) # only difference
# my (correct) solution:
def softmax(z):
assert len(z.shape) == 2
s = np.max(z, axis=1)
s = s[:, np.newaxis] # necessary step to do broadcasting
e_x = np.exp(z - s)
div = np.sum(e_x, axis=1)
div = div[:, np.newaxis] # dito
return e_x / div
Desertnauts를 예로 들어 보겠습니다.
x1 = np.array([[1, 2, 3, 6]]) # notice that we put the data into 2 dimensions(!)
이것은 출력입니다.
your_softmax(x1)
array([[ 0.00626879, 0.01704033, 0.04632042, 0.93037047]])
desertnaut_softmax(x1)
array([[ 1., 1., 1., 1.]])
softmax(x1)
array([[ 0.00626879, 0.01704033, 0.04632042, 0.93037047]])
이 상황에서 desernauts 버전이 실패한다는 것을 알 수 있습니다. (입력이 np.array ([1, 2, 3, 6])와 같은 1 차원 인 경우에는 그렇지 않습니다.
이제 2 차원 입력을 사용하는 이유 때문에 3 개의 샘플을 사용할 수 있습니다. 다음 x2는 desernauts 예제의 것과 다릅니다.
x2 = np.array([[1, 2, 3, 6], # sample 1
[2, 4, 5, 6], # sample 2
[1, 2, 3, 6]]) # sample 1 again(!)
이 입력은 3 개의 샘플이 포함 된 배치로 구성됩니다. 그러나 샘플 1과 3은 본질적으로 동일합니다. 우리는 이제 3 행의 softmax 활성화를 기대합니다. 여기서 첫 번째는 세 번째와 동일해야하며 x1의 활성화와 동일해야합니다!
your_softmax(x2)
array([[ 0.00183535, 0.00498899, 0.01356148, 0.27238963],
[ 0.00498899, 0.03686393, 0.10020655, 0.27238963],
[ 0.00183535, 0.00498899, 0.01356148, 0.27238963]])
desertnaut_softmax(x2)
array([[ 0.21194156, 0.10650698, 0.10650698, 0.33333333],
[ 0.57611688, 0.78698604, 0.78698604, 0.33333333],
[ 0.21194156, 0.10650698, 0.10650698, 0.33333333]])
softmax(x2)
array([[ 0.00626879, 0.01704033, 0.04632042, 0.93037047],
[ 0.01203764, 0.08894682, 0.24178252, 0.65723302],
[ 0.00626879, 0.01704033, 0.04632042, 0.93037047]])
나는 이것이 내 해결책의 경우라는 것을 알 수 있기를 바랍니다.
softmax(x1) == softmax(x2)[0]
array([[ True, True, True, True]], dtype=bool)
softmax(x1) == softmax(x2)[2]
array([[ True, True, True, True]], dtype=bool)
또한 TensorFlows softmax 구현 결과는 다음과 같습니다.
import tensorflow as tf
import numpy as np
batch = np.asarray([[1,2,3,6],[2,4,5,6],[1,2,3,6]])
x = tf.placeholder(tf.float32, shape=[None, 4])
y = tf.nn.softmax(x)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(y, feed_dict={x: batch})
그리고 결과 :
array([[ 0.00626879, 0.01704033, 0.04632042, 0.93037045],
[ 0.01203764, 0.08894681, 0.24178252, 0.657233 ],
[ 0.00626879, 0.01704033, 0.04632042, 0.93037045]], dtype=float32)