梯度反向传播过程是如何处理repeat函数的

举个例子

python 复制代码
import torch

# 假设有一个简单的计算图
x = torch.tensor(2.0, requires_grad=True)
c=x.repeat(2,1)
y = c ** 2


print(x,"\n",c,"\n",y)
torch.sum(y)

z = torch.sum(y)

# 计算梯度
grads = torch.autograd.grad(z, x)
# 打印梯度
print("Gradient of z w.r.t. x:", grads)

输出

python 复制代码
tensor(2., requires_grad=True) 
 tensor([[2.],
        [2.]], grad_fn=<RepeatBackward0>) 
 tensor([[4.],
        [4.]], grad_fn=<PowBackward0>)
Gradient of z w.r.t. x: (tensor(8.),)

在你的代码中,首先创建了一个张量 x,然后使用 repeat 函数将其在第0维(行)上重复2次,形成一个形状为 (2, 1) 的张量 c。然后,计算了 c 的平方,得到张量 y。最后,对 y 求和,得到标量张量 z。

因为 z 是一个标量,所以可以对它对 x 求梯度。现在让我们来分析一下为什么计算出的梯度是8:

首先,我们有 y = c ** 2,其中 c 是重复了两次的 x。所以 y 的值为 [4.0, 4.0]。然后,我们对 y 求和,得到 z = 8.0。

接下来,我们要计算 z 对 x 的梯度。由于 z 是标量,所以 torch.autograd.grad 函数的返回值是一个包含一个元素的元组,即 (grad_x,)。因此,grads 的值是一个包含一个张量的元组。在这种情况下,梯度的计算是通过链式法则完成的,即 dz/dx = dz/dy * dy/dc * dc/dx。在这里,dz/dy 是1,因为 z 是 y 的总和,dy/dc 是2,因为 y 中每个元素对 c 的导数都是2,dc/dx 是2,因为 c 是通过将 x 重复两次得到的,所以 x 对 c 的导数是2。因此, dz/dx = 1 * 2 * 2 = 4 * 2 = 8。

因此,计算出的梯度是8。

太神奇了,dc/dx的结果就是重复的次数!,那其实repeat函数的效果相对于放大了repeat对象的学习率,放大倍数就是repeat的次数,所以慎用repeat呀!

相关推荐
七夜zippoe几秒前
数据可视化高级技巧:Matplotlib + Seaborn实战大全
python·信息可视化·matplotlib·数据可视化·seaborn·gridspec
郝学胜-神的一滴几秒前
线性判别分析(LDA)原理详解与实战应用
人工智能·python·程序人生·算法·机器学习·数据挖掘·sklearn
徐同保2 分钟前
python使用vscode打断点调试
开发语言·python
小鸡吃米…2 分钟前
机器学习 - 对抗性机器学习
人工智能·python·机器学习
蓝海星梦4 分钟前
GRPO 算法演进——奖励设计篇
论文阅读·人工智能·深度学习·算法·自然语言处理·强化学习
gentle coder6 分钟前
【langchain】agent部署的基础入门代码(持续更新中~)
python·langchain·react
我材不敲代码7 分钟前
深度学习的准备工作:CUDA安装配置、pytorch库、torchvision库、torchaudio库安装
人工智能·pytorch·深度学习
ZCXZ12385296a14 分钟前
汽车损伤检测技术实现:YOLO13-C3k2-ConvFormer模型优化与性能分析_1
python
Network_Engineer16 分钟前
从零手写Transformer:基于每一步shape变化拆解与PyTorch实现
人工智能·pytorch·深度学习·transformer
晨非辰16 分钟前
Linux包管理器速成:yum/apt双精要/镜像源加速/依赖解析30分钟通解,掌握软件安装的艺术与生态哲学
linux·运维·服务器·c++·人工智能·python