Vì vậy, đây thực sự là một bình luận cho câu trả lời của Sahnaut nhưng tôi chưa thể bình luận về nó vì danh tiếng của tôi. Như ông đã chỉ ra, phiên bản của bạn chỉ đúng nếu đầu vào của bạn bao gồm một mẫu duy nhất. Nếu đầu vào của bạn bao gồm một số mẫu, nó là sai. Tuy nhiên, giải pháp của Sahnaut cũng sai. Vấn đề là một khi anh ta lấy đầu vào 1 chiều và sau đó anh ta lấy đầu vào 2 chiều. Hãy để tôi chỉ cho bạn điều này.
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
Hãy lấy ví dụ về sa mạc:
x1 = np.array([[1, 2, 3, 6]]) # notice that we put the data into 2 dimensions(!)
Đây là đầu ra:
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]])
Bạn có thể thấy rằng phiên bản desernauts sẽ thất bại trong tình huống này. (Sẽ không nếu đầu vào chỉ là một chiều như np.array ([1, 2, 3, 6]).
Bây giờ cho phép sử dụng 3 mẫu vì đó là lý do tại sao chúng tôi sử dụng đầu vào 2 chiều. X2 sau đây không giống với ví dụ từ desernauts.
x2 = np.array([[1, 2, 3, 6], # sample 1
[2, 4, 5, 6], # sample 2
[1, 2, 3, 6]]) # sample 1 again(!)
Đầu vào này bao gồm một lô với 3 mẫu. Nhưng mẫu một và ba về cơ bản là giống nhau. Bây giờ chúng tôi mong đợi 3 hàng kích hoạt softmax trong đó đầu tiên phải giống với thứ ba và cũng giống như kích hoạt x1 của chúng tôi!
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]])
Tôi hy vọng bạn có thể thấy rằng đây chỉ là trường hợp với giải pháp của tôi.
softmax(x1) == softmax(x2)[0]
array([[ True, True, True, True]], dtype=bool)
softmax(x1) == softmax(x2)[2]
array([[ True, True, True, True]], dtype=bool)
Ngoài ra, đây là kết quả của việc thực hiện softmax của TensorFlows:
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})
Và kết quả:
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)