李沐矩阵公式推导与过程答疑


07节.自动求导

问题1:MulBackward0是指什么?

回答:MulBackward0 是 PyTorch 中自动微分引擎的一部分,它表示一个张量是通过乘法操作得到的,并且在反向传播时用于计算梯度。在 PyTorch 中,每个张量都有一个 grad_fn 属性,这个属性引用了一个创建了该张量的 Function。对于通过乘法操作得到的张量,其 grad_fn 就是 MulBackward0
这里的“张量是通过乘法操作得到的”意味着:

  1. 有一个或多个原始张量(在这个例子中是a和b)。

  2. 这些原始张量经过乘法操作(*)。

  3. 乘法操作的结果是一个新张量(在这个例子中是c)。

  4. 这个新张量c的grad_fn属性被设置为MulBackward0,这是一个用于在反向传播中计算梯度的函数。

    在更复杂的情况下,如果涉及多个变量和操作,PyTorch 的自动微分引擎会构建一个计算图,并使用这些 grad_fn 来逐步计算每个变量的梯度。

问题2:grad_fn有哪些取值

在PyTorch中,grad_fn属性是用于自动微分的关键属性,它指向创建当前张量的函数。这个属性对于自动计算梯度至关重要,因为它记录了张量在计算图中的来源和创建方式。以下是一些常见的grad_fn取值及其对应的操作:

  1. AddBackward0: 表示张量是通过加法操作创建的。
  2. MulBackward0: 表示张量是通过乘法操作创建的。
  3. MatMulBackward: 表示张量是通过矩阵乘法操作创建的。
  4. DivBackward0: 表示张量是通过除法操作创建的。
  5. SumBackward0: 表示张量是通过求和操作创建的。
  6. MeanBackward0: 表示张量是通过求均值操作创建的。
  7. MaxBackward0: 表示张量是通过取最大值操作创建的。
  8. MinBackward0: 表示张量是通过取最小值操作创建的。
  9. SoftmaxBackward: 表示张量是通过softmax操作创建的。
  10. LogSoftmaxBackward: 表示张量是通过对数softmax操作创建的。
  11. Conv2dBackward: 表示张量是通过二维卷积操作创建的。
  12. BatchNormBackward: 表示张量是通过批量归一化操作创建的。

这些grad_fn是反向传播过程中计算梯度的基本单元。当你调用.backward()方法时,PyTorch会根据grad_fn回溯计算图中的每个操作,从而计算出每个参数的梯度。

问题3:计算图的显示构造和隐式构造

在深度学习中,自动求导(Automatic Differentiation,AD)是一种用来计算导数的技术,它对于训练神经网络至关重要,因为它允许我们高效地计算损失函数相对于模型参数的梯度。自动求导可以通过两种方式实现:显示构造(Explicit Construction)和隐式构造(Implicit Construction)。

  1. 显示构造(Explicit Construction)

    • 在显示构造中,计算图是显式地构建出来的。这意味着在程序运行时,会创建一个数据结构来表示计算图,其中包含了所有的操作和变量。
    • 这种方法通常使用图数据结构来存储操作和变量之间的依赖关系。
    • 优点是直观,易于理解和调试,因为整个计算过程是显式可见的。
    • 缺点是可能会增加内存的使用,因为需要存储整个计算图。
  2. 隐式构造(Implicit Construction)

    • 隐式构造不直接构建计算图,而是在运行时动态地计算梯度。
    • 这种方法通常使用一种称为“反向传播”(Backpropagation)的技术,它通过链式法则递归地计算导数。
    • 优点是内存使用效率更高,因为不需要存储整个计算图,只需要在需要计算梯度时进行计算。
    • 缺点是可能不如显示构造直观,对于复杂的模型,调试和理解计算过程可能更加困难。

在实际应用中,如PyTorch和TensorFlow这样的深度学习框架,通常提供了自动求导的功能。PyTorch使用动态计算图(Dynamic Computational Graph),它在每次前向传播时构建计算图,并在反向传播时自动计算梯度,这是隐式构造的一种实现。而TensorFlow 1.x版本使用的是静态计算图(Static Computational Graph),它在定义模型时构建计算图,这是显示构造的一种实现。

在最新的TensorFlow 2.x版本中,也支持了动态计算图,使得用户体验更加接近于PyTorch。

这两种方法各有优势,选择哪一种取决于具体的应用场景和个人偏好。

问题4:正向传递和反向传递中,正向传递都保存了哪些变量

写在前面:反向传递的主要对象是loss(标量函数),自动微分的grad启动,需要先进行backward

在深度学习中,正向传递(forward pass)和反向传递(backward pass)是训练神经网络的两个关键步骤。在正向传递中,输入数据通过网络,每一层都会计算出相应的输出,直到最终产生预测结果。而在反向传递中,则是通过计算损失函数关于网络参数的梯度,来更新网络的权重。

在正向传递过程中,为了有效地进行反向传递,通常需要保存以下变量:

  1. 输入数据:网络的输入,用于在反向传递时计算梯度。

  2. 层的输出:每一层的输出值,这些值会作为下一层的输入,并且在计算梯度时需要用到。

  3. 层的参数:包括权重和偏置等,这些参数在反向传递中用于计算梯度。

  4. 中间变量:某些操作可能依赖于中间变量,比如在计算激活函数之前的数据,这些中间变量在反向传递中可能需要用到。

  5. 激活函数的输出:激活函数的输出不仅用于当前层的输出,还用于反向传递中计算梯度。

  6. 损失函数的值:在训练过程中,需要计算损失函数关于预测结果的梯度。

在某些深度学习框架中,如PyTorch,正向传递时会自动保存这些变量,以便在反向传递时使用。这种机制通常被称为自动微分(automatic differentiation)。

需要注意的是,不是所有的变量都需要保存。一些临时变量,比如中间的加法结果,通常不需要保存,因为它们可以通过原始变量重新计算得到。但是,如上所述的变量通常需要保存,以便在反向传递中有效地计算梯度。

问题5:zero_是什么写法

在PyTorch中,zero_() 是一个原地操作(in-place operation),它用于将一个张量(tensor)的所有元素设置为0。这个操作会直接修改原张量,而不是创建一个新的张量。

这里的下划线(_)表示这是一个原地操作。PyTorch中的许多操作都有原地和非原地两种版本。原地操作会直接修改输入的数据,而非原地操作会返回一个新的数据副本。

例如,对于一个张量 x,你可以使用 x.zero_() 来将所有元素设置为0,这会直接修改 x。如果你想要保留原始的 x 并创建一个新的全0张量,你可以使用 x.new_zeros() 或者 torch.zeros_like(x)

在梯度计算的上下文中,x.grad.zero_() 用于清除之前计算的梯度,以确保在新的梯度计算中不会累积旧的梯度值。这是为了防止梯度累积,确保每次计算的梯度都是针对当前的参数状态。

所以每算一次新的梯度之前,都要做梯度的清零工作

问题6:反向求导的对象默认为标量函数,当出现向量函数时,有什么操作手段?

向量的反向计算:通常会计算一批(batch)训练样本中每个组成部分的损失函数的导数。
对此,我们的目的不是计算微分矩阵,而是单独计算批量中每个样本的偏导数之和。

x.grad.zero_()
y = x * x
u = y.detach()
z = u * x

z.sum().backward()#所以可以先求和,在反向传递,得到sum(grad)
x.grad == u

tensor([True, True, True, True])

问题7:线性回归方程解析解的计算过程

解析解 w ∗ = ( X ⊤ X ) − 1 X ⊤ y w^* = \left(X^{\top}X\right)^{-1}X^{\top}y w=(XX)1Xy的求导过程涉及对损失函数

∥ y − X w ∥ 2 \|y - Xw\|^2 yXw2

(L(w) = \frac{1}{2}|y - Xw|^2) 的最小化。这里我们使用梯度下降法的思路,通过求损失函数对权重 (w) 的导数(梯度),并令其为零来找到最小值。

步骤 1: 定义损失函数

首先,定义损失函数 (L(w)):
KaTeX parse error: Undefined control sequence: \[ at position 1: \̲[̲ L(w) = \frac{1…
这里 (|y - Xw|^2) 表示预测值和实际值之间的误差平方和。

步骤 2: 展开损失函数

将损失函数展开:
[
L(w) = \frac{1}{2} (y - Xw)^{\top} (y - Xw)
]
这里使用了向量内积的性质。

步骤 3: 求导

为了找到最小化损失函数的 (w),我们需要对 (L(w)) 关于 (w) 求导,并令导数为0。首先计算 (L(w)) 的梯度:
[
\frac{\partial L(w)}{\partial w} = \frac{\partial}{\partial w} \left( \frac{1}{2} (y - Xw)^{\top} (y - Xw) \right)
]
使用链式法则,我们得到:
[
\frac{\partial L(w)}{\partial w} = \frac{1}{2} \left( -X^{\top} (y - Xw) + (y - Xw)^{\top} X \right)
]
由于 (X^{\top} (y - Xw)) 是一个向量,我们可以进一步简化为:
[
\frac{\partial L(w)}{\partial w} = -X^{\top} (y - Xw) + X^{\top} (y - Xw) = 0
]
这里 (-X^{\top} (y - Xw)) 和 (X^{\top} (y - Xw)) 相互抵消。

步骤 4: 解方程

将导数设为0,我们得到:
[
-X^{\top} (y - Xw) = 0
]
简化得到:
[
X^{\top} y - X^{\top} Xw = 0
]
进一步整理得到:
[
X^{\top} Xw = X^{\top} y
]
解这个方程,我们得到:
[
w = (X^{\top} X)^{-1} X^{\top} y
]
这就是线性回归的解析解。

总结

通过上述步骤,我们通过求导和解方程得到了线性回归模型的最优权重向量 (w)。这个过程展示了如何从损失函数的最小化问题中得到解析解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值