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?
result=np.zeros_like(x), that creates an array of integers ifxis an array of integers. When you assign, term by term, the results of the normalization (all numbers are in interval0<n<1) to an array of integers, these normalized numbers are converted to integers and hence forced to zero. On the contrary, the non normalized exponentials are just rounded toward zero. If you want to use a loop, you can instantiateresultasnp.zeros(x.shape), but if you'd like to: 1) not use an auxiliary array and 2) remove the loop, please have a look at my answer below. ciao