Following https://classroom.udacity.com/courses/ud730/lessons/6370362152/concepts/63815621490923, I'm trying to write a "softmax" function which, when given a 2-dimensional array as input, calculates the softmax of each column. I wrote the following script to test it:
import numpy as np
#scores=np.array([1.0,2.0,3.0])
scores=np.array([[1,2,3,6],
[2,4,5,6],
[3,8,7,6]])
def softmax(x):
if x.ndim==1:
S=np.sum(np.exp(x))
return np.exp(x)/S
elif x.ndim==2:
result=np.zeros_like(x)
M,N=x.shape
for n in range(N):
S=np.sum(np.exp(x[:,n]))
result[:,n]=np.exp(x[:,n])/S
return result
else:
print("The input array is not 1- or 2-dimensional.")
s=softmax(scores)
print(s)
However, the result "s" turns out to be an array of zeros:
[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]
If I remove the "/S" in the for-loop, the 'un-normalized' result is as I would expect it to be; somehow the "/S" division appears to make all the elements zero instead dividing each element by S as I would expect it to. What is wrong with the code?
The reason for the "zeros" lies in the data type of the inputs, which are of the "int" type. Converting the input to "float" solved the problem:
import numpy as np
#scores=np.array([1.0,2.0,3.0])
scores=np.array([[1,2,3,6],
[2,4,5,6],
[3,8,7,6]])
def softmax(x):
x=x.astype(float)
if x.ndim==1:
S=np.sum(np.exp(x))
return np.exp(x)/S
elif x.ndim==2:
result=np.zeros_like(x)
M,N=x.shape
for n in range(N):
S=np.sum(np.exp(x[:,n]))
result[:,n]=np.exp(x[:,n])/S
return result
else:
print("The input array is not 1- or 2-dimensional.")
s=softmax(scores)
print(s)
Note that I've added "x=x.astype(float)" to the first line of the function definition. This yields the expected output:
[[ 0.09003057 0.00242826 0.01587624 0.33333333]
[ 0.24472847 0.01794253 0.11731043 0.33333333]
[ 0.66524096 0.97962921 0.86681333 0.33333333]]