-
-
Save stober/1946926 to your computer and use it in GitHub Desktop.
#! /usr/bin/env python | |
""" | |
Author: Jeremy M. Stober | |
Program: SOFTMAX.PY | |
Date: Wednesday, February 29 2012 | |
Description: Simple softmax function. | |
""" | |
import numpy as np | |
npa = np.array | |
def softmax(w, t = 1.0): | |
e = np.exp(npa(w) / t) | |
dist = e / np.sum(e) | |
return dist | |
if __name__ == '__main__': | |
w = np.array([0.1,0.2]) | |
print softmax(w) | |
w = np.array([-0.1,0.2]) | |
print softmax(w) | |
w = np.array([0.9,-10]) | |
print softmax(w) |
Another edit that made id PEP8 conform and use NumPyDocs:
#! /usr/bin/env python
"""
Author: Jeremy M. Stober, edits by Martin Thoma
Program: softmax.py
Date: Wednesday, February 29 2012 and July 31 2014
Description: Simple softmax function.
"""
import numpy
def softmax(w, t=1.0):
"""Calculate the softmax of a list of numbers w.
Parameters
----------
w : list of numbers
t : float
Return
------
a list of the same length as w of non-negative numbers
Examples
--------
>>> softmax([0.1, 0.2])
array([ 0.47502081, 0.52497919])
>>> softmax([-0.1, 0.2])
array([ 0.42555748, 0.57444252])
>>> softmax([0.9, -10])
array([ 9.99981542e-01, 1.84578933e-05])
>>> softmax([0, 10])
array([ 4.53978687e-05, 9.99954602e-01])
"""
e = numpy.exp(numpy.array(w) / t)
dist = e / numpy.sum(e)
return dist
if __name__ == "__main__":
import doctest
doctest.testmod()
Hi, this code is 3x faster and returns the same results.
import numpy as np
npa = np.array
def softmax(w, t = 1.0):
e = np.exp(npa(w) / t)
dist = e / np.sum(e)
return dist
def softmax_2(x):
e_x = np.exp(x - np.max(x))
out = e_x / e_x.sum()
return out
w = np.array([0.1,0.2])
%timeit softmax(w)
10000 loops, best of 3: 25.7 µs per loop
%timeit softmax_2(w)
100000 loops, best of 3: 8.83 µs per loop
#! /usr/bin/env python
import numpy as np
def softmax(w, t = 1.0):
e = np.exp(w, axes=0)
dist = e / np.sum(e)
return dict
#! /usr/bin/env python
import numpy as np
def softmax(w, t=1.0):
e = np.exp(w)
dist = e/np.sum(e, axis=0)
return dist
correct spelling @ppaulojr
alex2awesome,
%timeit softmax(w)
The slowest run took 4.66 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 9.41 µs per loop
%timeit softmax_2(w)
The slowest run took 6.51 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 10.9 µs per loop
But it can for some be better, because in some cases "softmax" breaks because of too high values when "softmax_2" lives on.
import numpy as np
space = np.linspace(-0, 300000000000, n)
softmax_2(space)
will survive while softmax will be dead even after
import numpy as np
space = np.linspace(-0, 3000, 10)
softmax(space)
So I would indeed highly recommend to use your softmax_2 function instead.
Adapting for 2-d array input x
def softmax(x):
if x.ndim == 1:
x = x.reshape([1, x.size])
softmaxInvx = x - np.max(x, 1).reshape([x.shape[0],1]);
matExp = np.exp(softmaxInvx)
return `matExp/np.sum(matExp,axis=1).reshape([matExp.shape[0],1]);
Vote for @piyushbhardwaj
A clearer version with doctest:
def softmax(x):
'''
>>> res = softmax(np.array([0, 200, 10]))
>>> np.sum(res)
1.0
>>> np.all(np.abs(res - np.array([0, 1, 0])) < 0.0001)
True
>>> res = softmax(np.array([[0, 200, 10], [0, 10, 200], [200, 0, 10]]))
>>> np.sum(res, axis=1)
array([ 1., 1., 1.])
>>> res = softmax(np.array([[0, 200, 10], [0, 10, 200]]))
>>> np.sum(res, axis=1)
array([ 1., 1.])
'''
if x.ndim == 1:
x = x.reshape((1, -1))
max_x = np.max(x, axis=1).reshape((-1, 1))
exp_x = np.exp(x - max_x)
return exp_x / np.sum(exp_x, axis=1).reshape((-1, 1))
labels = [0, 0, 0, 0, 0.68, 0.32, 0, 0, 0, 0]
%timeit softmax = np.exp([element for element in labels]) / np.sum(np.exp([element for element in labels]))
The slowest run took 5.03 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 12.2 µs per loop
It can be simple one liner.
def softmax(x):
return np.exp(x)/np.sum(np.exp(x),axis=0)
I've adapted your code to work with matrix input.
Thanks!
def softmax(w):
w = numpy.array(w)