hhhhh

发布于:2024-07-27 ⋅ 阅读:(38) ⋅ 点赞:(0)
x = torch.tensor([1.0,0.],[-1.,1.],requires_grad=True)
z = x.pow(2).sum()
z.backward()
x.grad

在这段代码中,我们利用 PyTorch 进行自动求梯度,下面详细解释代码的每一个部分及其在反向传播中的作用。同时,我们也将介绍函数对象和叶子节点的概念。

  1. 创建张量

    x = torch.tensor([[1.0, 0.], [-1., 1.]], requires_grad=True)
    
    • 这里我们创建了一个二维张量 x,其内容是 [[1.0, 0.], [-1., 1.]]
    • 设置 requires_grad=True,意味着我们希望跟踪这个张量的操作,以便进行自动求梯度。PyTorch 记录所有对该张量的操作,以便在反向传播时能够计算出梯度。
    • 此外, x 是一个叶子节点,这是指在计算图的最底层的张量,它是用户直接创建的张量或从其他张量分割而来,不是通过其他张量的操作结果产生的。
  2. 定义计算图的输出

    z = x.pow(2).sum()
    
    • x.pow(2) 是对 x 中的每个元素进行平方运算,生成一个新的张量,这个新张量并不是用户直接创建的,而是通过操作 x 生成,因此它不是叶子节点。
    • 接着,我们调用 .sum(),它会计算所有元素的和,结果保存在 z 中。至此,计算图已经构建完成,PyTorch 知道如何从 z 计算回 x
  3. 反向传播

    z.backward()
    
    • 这一行触发了反向传播过程,计算出 z 相对于 x 的梯度。
    • PyTorch 通过链式法则自动计算每个节点的梯度,其中涉及的操作和节点形成的计算图使得这些计算变得直接。
    • 具体来说,由于 ( z = x 1 2 + x 2 2 + x 3 2 + x 4 2 z = x_1^2 + x_2^2 + x_3^2 + x_4^2 z=x12+x22+x32+x42 ),对每个元素分别求导可得:
      • 对于 ( x 1 = 1.0 x_1 = 1.0 x1=1.0 ),( ∂ z ∂ x 1 = 2 ⋅ x 1 = 2 ⋅ 1.0 = 2 \frac{\partial z}{\partial x_1} = 2 \cdot x_1 = 2 \cdot 1.0 = 2 x1z=2x1=21.0=2 )
      • 对于 ( x 2 = 0.0 x_2 = 0.0 x2=0.0 ),( ∂ z ∂ x 2 = 2 ⋅ x 2 = 2 ⋅ 0.0 = 0 \frac{\partial z}{\partial x_2} = 2 \cdot x_2 = 2 \cdot 0.0 = 0 x2z=2x2=20.0=0 \
      • 对于 ( x 3 = − 1.0 x_3 = -1.0 x3=1.0 ),( ∂ z ∂ x 3 = 2 ⋅ x 3 = 2 ⋅ − 1.0 = − 2 \frac{\partial z}{\partial x_3} = 2 \cdot x_3 = 2 \cdot -1.0 = -2 x3z=2x3=21.0=2 )
      • 对于 ( x 4 = 1.0 x_4 = 1.0 x4=1.0 ),( ∂ z ∂ x 4 = 2 ⋅ x 4 = 2 ⋅ 1.0 = 2 \frac{\partial z}{\partial x_4} = 2 \cdot x_4 = 2 \cdot 1.0 = 2 x4z=2x4=21.0=2 )
  4. 查看梯度

    x.grad
    
    • 这一行返回 x 的梯度,结果应为:tensor([[ 2., 0.], [-2., 2.]])。这对应于从反向传播过程中计算得到的梯度值。
  • 在 PyTorch 中,任何通过运算生成的张量都可以看作是一个函数对象,它们代表了多个操作和计算结果的链表。例如,z 就是一个非叶子节点,它由 x 计算得到,而这些操作形成了一个计算图,这样在计算梯度时,我们就知道如何回溯。

网站公告

今日签到

点亮在社区的每一天
去签到