I am trying to apply a softmax function to a numpy array. But I am not getting the desired results. This is the code I have tried:
import numpy as np
x = np.array([[1001,1002],[3,4]])
softmax = np.exp(x - np.max(x))/(np.sum(np.exp(x - np.max(x)))
print softmax
I think the x - np.max(x)
code is not subtracting the max of each row. The max needs to be subtracted from x to prevent very large numbers.
This is supposed to output
np.array([
[0.26894142, 0.73105858],
[0.26894142, 0.73105858]])
But I am getting:
np.array([
[0.26894142, 0.73105858],
[0, 0]])
The
x - np.max(x)
code is not doing row-wise subtraction. Let's do it step-wise. First we will make a 'maxes' array by tiling or making a copy of the column:This will create a 2X2 matrix which will correspond to the maxes for each row by making a duplicate column(tile). After this you can do:
You should get your result with this. The
axis = 1
is for the row-wise softmax you mentioned in the heading of your answer. Hope this helps.EDIT. As of version 1.2.0, scipy includes softmax as a special function:
https://scipy.github.io/devdocs/generated/scipy.special.softmax.html
I wrote a very general softmax function operating over an arbitrary axis, including the tricky max subtraction bit. The function is below, and I wrote a blog post about it here.
How about this?
For taking
max
along the rows just specify the argument asaxis=1
and then convert the result as a column vector(but a 2D array actually) usingnp.newaxis/None
.In the last step, again when you take sum just specify the argument
axis=1
to sum it along the rows.My 5-liner (which uses scipy logsumexp for the tricky bits):
You may have to use
from scipy.misc import logsumexp
if you have an older scipy version.A convenient way to keep the axes that are consumed by "reduce" operations such as
max
orsum
is thekeepdims
keyword: