1

I have an anonymous function with "_" as parameters, I don't know what it means and why it is used here.

and function is:

f = lambda _: model.loss(X, y)[0]

grad_num = eval_numerical_gradient(f, model.params[name], verbose=False, h=1e-5)

model.loss:

def loss(self, X, y=None): # Unpack variables from the params dictionary W1, b1 = self.params['W1'], self.params['b1'] W2, b2 = self.params['W2'], self.params['b2'] h1, h1_cache = affine_relu_forward(X, W1, b1) scores, h2_cache = affine_forward(h1, W2, b2) # If y is None then we are in test mode so just return scores if y is None: return scores loss, grads = 0, {} loss, dscores = softmax_loss(scores, y) loss = loss + 0.5*self.reg*(np.sum(W2**2) + np.sum(W1**2)) dh1, grads['W2'], grads['b2'] = affine_backward(dscores,h2_cache) dX, grads['W1'], grads['b1'] = affine_relu_backward(dh1,h1_cache) grads['W1'] += self.reg*W1 grads['W2'] += self.reg*W2 return loss, grads 

and the function eval_numerical_gradient:

def eval_numerical_gradient(f, x, verbose=True, h=0.00001): fx = f(x) # evaluate function value at original point grad = np.zeros_like(x) # iterate over all indexes in x it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) while not it.finished: # evaluate function at x+h ix = it.multi_index oldval = x[ix] x[ix] = oldval + h # increment by h fxph = f(x) # evalute f(x + h) x[ix] = oldval - h fxmh = f(x) # evaluate f(x - h) x[ix] = oldval # restore # compute the partial derivative with centered formula grad[ix] = (fxph - fxmh) / (2 * h) # the slope if verbose: print(ix, grad[ix]) it.iternext() # step to next dimension return grad 

Loss function isn't complex, I want to know what the "_" represented and function in there.

8
  • This is typically used for anonymous variables that are required but of no use to the code. Commented Jul 25, 2019 at 8:02
  • Isn't used _, unused parameter. Commented Jul 25, 2019 at 8:02
  • 9
    Possible duplicate of What is the purpose of the single underscore "_" variable in Python? Your case is #3 in the accepted answer. Commented Jul 25, 2019 at 8:04
  • 1
    @Chillie It's definitely related but I'd not mark it as duplicated because of the specific use-case I describe in my answer. Without context the lambda in the OP could be implemented as lambda: model.loss(X, y)[0] but it can't, because the callback will pass an argument Commented Jul 25, 2019 at 8:08
  • 1
    @AndriyMakukha He can't because f is used as a callback that will be passed an argument. See my answer Commented Jul 25, 2019 at 8:10

2 Answers 2

5

It's a convention in Python to use _ for variables that are not going to be used later. There is no black magic involved and it is an ordinary variable name that behaves exactly as you'd expect.

In this case it is used because f is passed as a callback which will be passed an argument when it is called (fxph = f(x)).

If f would have been implemented as

f = lambda: model.loss(X, y)[0] 

then a TypeError: <lambda>() takes 0 positional arguments but 1 was given error will be raised.

Sign up to request clarification or add additional context in comments.

11 Comments

@ZhengfangXin Yes, but it is not related. If the lambda would have not accepted _ then the call fxph = f(x) would have failed with the error I show in my answer
@AzatIbrakov It is not a duplicate, let alone an "obvious" one. None of the answers there explain why it is used in the very specific use-case that this question shows
@ZhengfangXin The IDE and the interpreter do not care. They do care that f will accept an argument. They do not care how f calls that argument internally or if it even using it.
@ZhengfangXin There's nothing special about the name _ in this context. It is the same as f = lambda ignored_argument: x + y.
@ZhengfangXin Again. _ means nothing special. _ = 1 is exactly the same as x = 1. You get an error because you define a function that accepts a single argument but you pass it two arguments.
|
2

In your case, it's a convention, telling that the lambda parameter is not used (the answer from DeepSpace explain why).

General use:

You can use _ when you have to get a value but you do not use it. It is a python convention, developers use it to make their code more readable to other developers. With _, you say that you are aware that the variable is not used. Some IDE like PyCharm warn you if you don't:

def test(s): print("foobar") if __name__ == '__main__': test("barfoo") 

Will result of a warning in Pycharm for example:

warning

But not with _:

def test(_): print("foobar") if __name__ == '__main__': test("barfoo") 

Result no warning:

no warning

4 Comments

Why can not just call def test(): print('foobar')?
Because of the example ! Of course you can, it's just an example to show your how your IDE will behave. A better example maybe is with for loop: for _ in range(10): print('hello'), but it take more line to do and I want the answer to be concise.
I didn't downvote but it is not true to say that you use _ to tell your IDE something. _ is a python convention, developers use it to make their code more readable to other developers and IDE have adapted to help them using this convention.
Ok, not exactly true, but still not false. If IDE warn you, it's because it's a python convention and developers use it etc. Thanks, I will edit the answer to be more clear.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.