Reputation: 164
I am currently looking at the sklearn source code in github and I have encountered a line that bugs me. It's this one.
I understand the difference between copying by value and copying by reference (I guess the copy function from numpy is by value and x = y is by reference).
But clearly I don't understand the purpose of copying to itself the same variable as in
Can anyone throw some light upon this?
Thank you very much
Upvotes: 1
Views: 319
Reputation: 356
How would you suspect that the function will look like if you didn't assigned it back to the variable it already defined.
def softmax(X, copy=True):
"""
Calculate the softmax function.
The softmax function is calculated by
np.exp(X) / np.sum(np.exp(X), axis=1)
This will cause overflow when large values are exponentiated.
Hence the largest value in each row is subtracted from each data
point to prevent this.
Parameters
----------
X : array-like, shape (M, N)
Argument to the logistic function
copy : bool, optional
Copy X or not.
Returns
-------
out : array, shape (M, N)
Softmax function evaluated at every point in x
"""
def _softmax(X):
max_prob = np.max(X, axis=1).reshape((-1, 1))
X -= max_prob
np.exp(X, X)
sum_prob = np.sum(X, axis=1).reshape((-1, 1))
X /= sum_prob
return X
return _softmax(np.copy(X) if copy else X)
This makes the code less readable.
Overwriting a local variable when preprocessing the variable is normally accepted as it makes readable code. Adding a second variable will make understanding the code harder. In my example I tried to create code that was as easy to understand without any duplication. But you cannot read this code serial anymore. You first need to read the last statement _softmax(np.copy(X) if copy else X)
to understand how it is being used.
In performance this also introduces an additional call what you don't want in these low level functions.
Upvotes: 0
Reputation: 804
That softmax function offers to run inplace in order to save a duplication op, therefore overwriting the input X with the result of the softmax.
The copy is here to avoid changing the input in case it is needed elswhere.
X = np.copy(X)
replaces the original reference with a reference to the copy which is safe to modify.
Upvotes: 1