Skip to content

Instantly share code, notes, and snippets.

@stober
Created March 1, 2012 03:05
Show Gist options
  • Save stober/1946926 to your computer and use it in GitHub Desktop.
Save stober/1946926 to your computer and use it in GitHub Desktop.
Softmax in Python
#! /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)
@aelaguiz
Copy link

aelaguiz commented Jan 4, 2013

I've adapted your code to work with matrix input.

Thanks!

def softmax(w):
w = numpy.array(w)

maxes = numpy.amax(w, axis=1)
maxes = maxes.reshape(maxes.shape[0], 1)
e = numpy.exp(w - maxes)
dist = e / numpy.sum(e, axis=1)

return dist

@MartinThoma
Copy link

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()

@alex2awesome
Copy link

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

@ppaulojr
Copy link

#! /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

@bigsnarfdude
Copy link

#! /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

@ibmua
Copy link

ibmua commented May 19, 2016

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.

@piyushbhardwaj
Copy link

piyushbhardwaj commented Jan 13, 2017

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]);

@kigawas
Copy link

kigawas commented Jan 30, 2017

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))

@AFAgarap
Copy link

AFAgarap commented Sep 6, 2017

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

@rajans
Copy link

rajans commented Mar 21, 2018

It can be simple one liner.

def softmax(x):
return np.exp(x)/np.sum(np.exp(x),axis=0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment