DAY03:【pytorch】自动求导系统

发布于:2025-04-12 ⋅ 阅读:(79) ⋅ 点赞:(0)

1、torch.autograd.backward

# torch.autograd.backward(
#     tensor,
#     grad_tensors=None,
#     retain_graph=None,
#     create_graph=False
# )

功能:自动求取梯度

  • tensors:用于求导的张量
  • retain_graph:保存计算图
  • creat_graph:创建导数计算图,用于高阶求导
  • grad_tensors:多梯度权重

示例:

y = ( x + w ) ∗ ( w + 1 ) y = (x + w) * (w + 1) y=(x+w)(w+1)
a = x + w a = x + w a=x+w
b = w + 1 b = w + 1 b=w+1
y = a ∗ b y = a * b y=ab
∂ y ∂ w = ∂ y ∂ a ∂ a ∂ w + ∂ y ∂ b ∂ b ∂ w = 5 \frac{∂y}{∂w} = \frac{∂y}{∂a} \frac{∂a}{∂w} + \frac{∂y}{∂b} \frac{∂b}{∂w} = 5 wy=aywa+bywb=5

if True:
    w = torch.tensor([1.],requires_grad=True)
    x = torch.tensor([2.],requires_grad=True)

    a = torch.add(w, x)
    b = torch.add(w, 1)
    y = torch.mul(a, b)

    y.backward(retain_graph=True) # retain_graph=True表示不释放计算图
    print(w.grad, x.grad)

"""
输出:
tensor([5.]) tensor([2.])
"""
if True:
    w = torch.tensor([1.],requires_grad=True)
    x = torch.tensor([2.],requires_grad=True)

    a = torch.add(w, x)
    b = torch.add(w, 1)
    
    y0 = torch.mul(a, b)
    y1 = torch.add(a, b)

    loss = torch.cat([y0, y1], dim=0)
    grad_tensors = torch.tensor([1., 1.])
    loss.backward(gradient=grad_tensors)
    print(w.grad, x.grad)

"""
输出:
tensor([7.]) tensor([3.])
"""

2、torch.autograd.grad

# torch.autograd.grad(
#     outputs,
#     inputs,
#     grad_outputs=None,
#     retain_graph=None,
#     create_graph=False,
#     only_inputs=True,
#     allow_unused=False
# )

功能:求取梯度

  • ouputs:用于求导的张量
  • inputs:需要梯度的张量
  • create_graph:创建导数计算图,用于高阶求导
  • retain_graph:保存计算图
  • grad_outputs:多梯度权重
if True:
    x = torch.tensor([3.], requires_grad=True)
    y = torch.pow(x, 2) # y = x^2

    grad_1 = torch.autograd.grad(y, x, create_graph=True) # 计算y对x的导数
    print(grad_1) # grad_1 = 2*x = 6
    grad_2 = torch.autograd.grad(grad_1, x, create_graph=True) # 计算y对x的二阶导数
    print(grad_2) # grad_2 = 2

"""
输出:
(tensor([6.], grad_fn=<MulBackward0>),)
(tensor([2.], grad_fn=<MulBackward0>),)
"""

3、注意

3.1 梯度不自动清零

if True:
    w = torch.tensor([1.], requires_grad=True)
    x = torch.tensor([2.], requires_grad=True)

    for i in range(4):
        a = torch.add(w, x)
        b = torch.add(w, 1)
        y = torch.mul(a, b)

        y.backward()
        print(w.grad, x.grad)
        
        w.grad.zero_() # 清空梯度
        x.grad.zero_() # 清空梯度

"""
输出:
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
"""

3.2 依赖于叶子结点的结点,requires_grad默认为True

3.3 叶子结点不可执行in-place

if True:
    a = torch.ones((1, ))
    print(id(a), a)

    a = a + torch.ones((1, ))
    print(id(a), a) # 这里的a是一个新的tensor,和之前的a不是同一个tensor了

"""
输出:
2719495780496 tensor([1.])
2719495881744 tensor([2.])
"""
if True:
    a = torch.ones((1, ))
    print(id(a), a)

    a += torch.ones((1, ))
    print(id(a), a)

"""
输出:
2719495530336 tensor([1.])
2719495530336 tensor([2.])
"""

微语录:要往前走,就得先忘掉过去。


网站公告

今日签到

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