RussAbbott
RussAbbott

Reputation: 2738

How is this Python function read?

Wikipedia has the following example code for softmax.

>>> import numpy as np
>>> z = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0]
>>> softmax = lambda x : np.exp(x)/np.sum(np.exp(x))
>>> softmax(z)
array([0.02364054, 0.06426166, 0.1746813 , 0.474833  , 0.02364054 , 0.06426166, 0.1746813 ])

When I run it, it runs successfully. I don't understand how to read the lambda function. In particular, how can the parameter x refer to an array element in the numerator and span all the elements in the denominator?

[Note: The question this question presumably duplicates is about lambdas in general. This question is not necessarily about lambda. It is about how to read the np conventions. The answers by @Paul Panzer and @Mihai Alexandru-Ionut both answer my question. Too bad I can't check both simultaneously as answering the question.

To confirm that I understand their answers (and to clarify what my question was about):

]

Upvotes: 0

Views: 822

Answers (3)

Paul Panzer
Paul Panzer

Reputation: 53029

Three remarks.

The use of lambda in the example is actually bad style, cf. this paragraph from the Python style guide:

Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.

Yes:

def f(x): return 2*x

No:

f = lambda x: 2*x

The first form means that the name of the resulting function object is specifically 'f' instead of the generic ''. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)

Re the content. What you are seeing is array arithmetic. np.exp is a numpy ufunc it operates element-wise, so it will return an array of the same shape as its argument. np.sum is a reducing function, when called with an array as its sole argument it will return a scalar. The / operator is overloaded with a binary ufunc; like np.exp it operates element-wise. In addition, it does broadcasting: In this case the scalar denominator will be paired with every element of the array numerator resulting in an array.

And finally: Here is how to implement the softmax properly.

Upvotes: 1

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48367

I don't understand how to read the lambda function.

A lambda function is an anonymous function that is not bound to a name

In particular, how can the parameter x refer to an array element in the numerator and span all the elements in the denominator?

No, parameter x does not refer to an array element, but to the whole array. np.exp(x) method also returns a new array.

By writing np.exp(x)/np.sum(np.exp(x)) the array resulted from np.exp(x) will be divided to the sum and it means that every item from the array will be divided to that sum.

Upvotes: 1

Antwane
Antwane

Reputation: 22628

A lambda expression is like an anonymous function. In this context, the line

softmax = lambda x : np.exp(x)/np.sum(np.exp(x))

is equivalent to

def softmax(x):
    return np.exp(x)/np.sum(np.exp(x))

Upvotes: 1

Related Questions