nox 发表于 2023-4-16 00:32:41

求大佬帮我解惑关于lambda的问题

以下是代码片段:
##numerical_gradient
def _numerical_gradient_1d(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    for idx in range(x.size):
      tmp_val = x
      x = float(tmp_val) + h
      fxh1 = f(x) # f(x+h)
      x = tmp_val - h
      fxh2 = f(x) # f(x-h)
      grad = (fxh1 - fxh2) / (2*h)
      x = tmp_val
    return grad
def numerical_gradient_2d(f, X):
    if X.ndim == 1:
      return _numerical_gradient_1d(f, X)
    else:
      grad = np.zeros_like(X)
      
      for idx, x in enumerate(X):
            grad = _numerical_gradient_1d(f, x)
      return grad
def gradient(x, t, network):
    loss_W = lambda W: loss(x, t, network)
    grads_W1 = numerical_gradient_2d(loss_W, network)
    grads_b1 = numerical_gradient_2d(loss_W, network)
    grads_W2 = numerical_gradient_2d(loss_W, network)
    grads_b2 = numerical_gradient_2d(loss_W, network)
    grads_W3 = numerical_gradient_2d(loss_W, network)
    grads_b3 = numerical_gradient_2d(loss_W, network)
    return grads_W1, grads_b1, grads_W2, grads_b2, grads_W3, grads_b3
gradient函数中的lambda W: loss(x, t, network)的用法我看不明白,W似乎并不是loss函数中的参数,请各位大佬提点一下,这属于哪一种用法?

isdkz 发表于 2023-4-16 00:34:43

在这个代码片段中,lambda W: loss(x, t, network)是一个匿名函数(lambda函数),它接受一个参数W。在这个匿名函数中,W并没有直接作用于loss函数。这里的lambda函数是为了将loss函数适配成只需要一个参数的版本,以便于后面调用numerical_gradient_2d函数时使用。

numerical_gradient_2d函数接受一个函数f作为参数,并在函数内部调用f(x)。在gradient函数中,loss_W是一个lambda函数,它将W作为参数。当numerical_gradient_2d调用loss_W(x)时,实际上是调用了loss(x, t, network)。这里的x是numerical_gradient_2d函数内部的局部变量,而loss函数的其他参数t和network是在定义loss_W时从外层作用域捕获的。

简而言之,这里的lambda函数用于将一个接受多个参数的函数(如loss)转换成只接受一个参数的函数(如loss_W),以便在其他地方使用。这种用法在Python中非常常见。

nox 发表于 2023-4-16 13:41:00

isdkz 发表于 2023-4-16 00:34
在这个代码片段中,lambda W: loss(x, t, network)是一个匿名函数(lambda函数),它接受一个参数W。在这个 ...

谢谢回答!只是仍有看不懂之处。
在这一行grads_W1 = numerical_gradient_2d(loss_W, network)时,应该是将loss_W和network传入numerical_gradient_2d函数,二者分别与参数f和X相对应。
而很明显loss(x, t, network)这个函数是包含三个形参的。
既然使用了lambda将loss封装成只含一个参数的函数,那么此时loss_W的形参应该就是W,那么程序是怎么判断network与x, t, network之间的对应关系的呢?

isdkz 发表于 2023-4-16 13:44:34

nox 发表于 2023-4-16 13:41
谢谢回答!只是仍有看不懂之处。
在这一行grads_W1 = numerical_gradient_2d(loss_W, network)时,应 ...

抱歉刚才的解释可能没有完全解决你的疑问。让我再详细解释一下。

在gradient函数中,numerical_gradient_2d函数实际上是在求loss函数关于network中权重矩阵和偏置项的梯度。因此,我们需要传递一个关于W的函数(这里是loss_W)给numerical_gradient_2d,这样它就能计算关于W的梯度。

当我们定义loss_W = lambda W: loss(x, t, network)时,我们创建了一个新的函数loss_W,它只接受一个参数W。在loss_W函数内部,我们调用loss(x, t, network)。这里,x和t是gradient函数的参数,而network是一个局部变量。当我们调用loss_W(W)时,实际上是在调用loss(x, t, network),其中W会替换network中的相应权重或偏置。

在gradient函数中,我们分别对network的不同部分求梯度,如:

grads_W1 = numerical_gradient_2d(loss_W, network)

这里我们传递了loss_W和network给numerical_gradient_2d。loss_W是我们定义的只接受一个参数的函数,而network是我们想要求梯度的权重矩阵。当numerical_gradient_2d调用loss_W(x)时,这个x实际上是network的副本。这意味着W会替换network中的对应权重矩阵,然后计算关于W的梯度。

同样的道理适用于其他权重矩阵和偏置项的梯度计算。希望这次解释能更好地解决你的疑问。

页: [1]
查看完整版本: 求大佬帮我解惑关于lambda的问题