PyTorch 从tensor.grad 看 backward(权重参数) 和 gradient accumulated

文章介绍了如何在PyTorch中创建张量,进行基本运算并使用`requires_grad`属性,以及`backward`方法来计算梯度。重点讲解了权重在梯度回传中的作用,包括均匀权重和非均匀权重的应用。
部署运行你感兴趣的模型镜像

1. 新建一个自变量 tensor x

import torch

x = torch.ones(1, requires_grad=True)
print(x)

1. 输出:

tensor([1.], requires_grad=True)

2. 写一个 forward

import torch

x = torch.ones(1, requires_grad=True)
y = x**2
z = x**3

3. y, z 都 backward

import torch

x = torch.ones(1, requires_grad=True)
y = x**2
z = x**3

y.backward()
z.backward()

print(x.grad)

3.输出

tensor([5.])

4. 单独 y backward

import torch

x = torch.ones(1, requires_grad=True)
y = x**2
z = x**3

y.backward()

print(x.grad)

4. 输出

tensor([2.])

5. 单独 z backward

import torch

x = torch.ones(1, requires_grad=True)
y = x**2
z = x**3

z.backward()

print(x.grad)

5. 输出

tensor([3.])

6. tensor.grad.zero_()

import torch

x = torch.ones(1, requires_grad=True)
y = x**2
y.backward()
print(x.grad)

x.grad.zero_()
z = x**3
z.backward()
print(x.grad)

输出:

tensor([2.])
tensor([3.])

向量形式

注意由于 x 此时不是标量,所以 执行 y.backward()的时候必须给一个参数。
参数的含义是权重。
gradient=torch.ones(y.size()) 中的 gradient 参数指定了每个 y 元素对于 x的梯度的权重。在这里,gradient 设置为全1的张量,表示每个 y 元素对于损失函数的梯度权重都是1。

这意味着所有的梯度将被等权重地传播回输入 x。如果你想要为不同的元素分配不同的权重,你可以修改 gradient 参数以实现不同的梯度计算策略。

import torch

x = torch.tensor([[-1.5], [2.7]], requires_grad=True)
print(x)

y = torch.empty([3,1])
y[0] = x[0]**2
y[1] = x[1]**3
y[2] = x[1]**4
y.backward(gradient=torch.ones(y.size()))
print(x.grad)


dy0 = 2*x[0]
dy1 = 3*x[1]**2
dy2 = 4*x[1]**3

dy_dx0 = dy0
dy_dx1 = dy1+dy2

print(dy_dx0)
print(dy_dx1)

输出

tensor([[-1.5000],
        [ 2.7000]], requires_grad=True)

tensor([[ -3.0000],
        [100.6020]])
        
tensor([-3.], grad_fn=<MulBackward0>)
tensor([100.6020], grad_fn=<AddBackward0>)

权重不一样

import torch

x = torch.tensor([[-1.5], [2.7]], requires_grad=True)
print(x)

y = torch.empty([3,1])
y[0] = x[0]**2
y[1] = x[1]**3
y[2] = x[1]**4
y.backward(gradient=torch.tensor([[0.5],[-2.],[1.5]]))
print(x.grad)


dy0 = 2*x[0]
dy1 = 3*x[1]**2
dy2 = 4*x[1]**3

dy_dx0 = 0.5*dy0
dy_dx1 = -2*dy1+1.5*dy2

print(dy_dx0)
print(dy_dx1)

输出

tensor([[-1.5000],
        [ 2.7000]], requires_grad=True)
tensor([[-1.5000],
        [74.3580]])
tensor([-1.5000], grad_fn=<MulBackward0>)
tensor([74.3580], grad_fn=<AddBackward0>)

您可能感兴趣的与本文相关的镜像

PyTorch 2.9

PyTorch 2.9

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

<think> 我们讨论PyTorch中的tensorgrad_fngrad属性。 首先,grad_fn是记录创建该Tensor的函数,用于反向传播。如果该Tensor是由用户直接创建的(例如通过`torch.tensor`),则grad_fn为None,我们称这样的Tensor为叶子节点。 其次,grad属性存储的是反向传播后计算得到的梯度值。对于叶子节点,如果设置了`requires_grad=True`,则梯度会累积到这里。 注意:在PyTorch中,默认情况下,新创建的tensor的`requires_grad`是False。 示例代码说明: import torch x = torch.tensor([1.0, 2.0], requires_grad=True) y = x * 2 z = y.mean() z.backward() 此时,x是叶子节点,它的grad_fn为None,而yz是由操作生成的,所以y.grad_fn指向MulBackward,z.grad_fn指向MeanBackward。 在调用z.backward()后,x.grad会存储梯度,即[0.5, 0.5](因为z = (2x1+2x2)/2 = (2+4)/2=3,对x1x2的偏导分别是1/2=0.5)。 注意:非叶子节点的梯度默认情况下是不保存的(除非使用`retain_grad()`),因此非叶子节点的grad属性通常为None。 下面我们详细解释: 1. grad_fn: 指向一个Function对象,该对象记录了创建该Tensor所使用的操作,用于构建反向传播图。 2. grad: 存储梯度值。对于叶子节点(即用户直接创建的tensor)且requires_grad=True,在调用backward后,这里会存储梯度。 注意事项: - 只有标量才能直接调用backward(),非标量需要传入一个与当前tensor形状相同的gradient参数(即梯度权重)。 - 多次反向传播时,梯度会累积(相加)。为了避免累积,需要在每次反向传播前将梯度清零(使用`x.grad.data.zero_()`)。 现在,根据规则,在回答后提出3-5个相关问题。 </think> 在PyTorch中,`grad_fn``grad`是Tensor的两个核心属性,用于实现自动微分: 1. **grad_fn**: - 记录创建当前Tensor的操作(如加法、乘法等) - 类型为`torch.autograd.Function`,指向反向传播所需的计算函数 - 用户创建的Tensor(叶子节点)此属性为`None` - 示例:`y = x * 2`中,`y.grad_fn = <MulBackward0>` 2. **grad**: - 存储反向传播后计算出的梯度值 - 初始值为`None`,调用`.backward()`后更新 - 仅对`requires_grad=True`的叶子节点有效 - 梯度会累积(除非手动清零) ```python import torch x = torch.tensor([3.0], requires_grad=True) y = x ** 2 # y.grad_fn = <PowBackward0> y.backward() print(x.grad) # 输出: tensor([6.]) (dy/dx = 2x) ``` **关键区别**: | 属性 | 作用 | 存储位置 | 叶子节点 | 非叶子节点 | |---------|------------------------------|---------------|----------|------------| | `grad_fn` | 记录创建Tensor的操作 | 所有计算图节点 | None | 有值 | | `grad` | 存储反向传播计算的梯度值 | 仅叶子节点 | 有值 | 通常None | 注意事项: 1. 非叶子节点的梯度默认不保留(节省内存) 2. 使用`retain_grad()`可保留非叶子节点梯度 3. 梯度累积需手动清零:`x.grad.zero_()`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

培之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值