python - Pytorch 梯度计算
问题描述
我试图弄清楚该功能是如何grad
工作的。
这是我的代码:
A = torch.Tensor(2, 3).uniform_(-1, 1).requires_grad_()
B = torch.Tensor(3, 1).uniform_(-1, 1).requires_grad_()
o = torch.matmul(A,B)
print("A : ", A)
print("B : ", B)
do_dinput = torch.autograd.grad(o, A, grad_outputs=torch.ones(2, 1))
print('Size do/dA :', (do_dinput[0].size()))
我期待torch.Size([1, 3])
被打印出来,因为AB
wrt的导数A
是B^T
. 然而,我得到了torch.Size([2, 3])
.
我的代码有问题,还是我遗漏了什么?
解决方案
你得到的是从 o 开始的梯度,通过计算图反向传播到 A。最后你得到了 A 中每个值的梯度。
与执行以下操作相同
A = torch.Tensor(2, 3).uniform_(-1, 1).requires_grad_()
B = torch.Tensor(3, 1).uniform_(-1, 1).requires_grad_()
o = torch.matmul(A,B).sum()
o.backward()
print("A : ", A)
print("B : ", B)
print(A.grad)
A.grad
在这个例子中和do_dinput
是一样的。如果您查看 grad 张量,它就B^T
在两行中。
为了让它更直观地发生了什么。我们有 A 和 B 作为输入,还有一些函数 f(...) 将 A 和 B 中的所有值作为输入并计算一些值。在这种情况下,函数是 sum(AB)。
注意:求和不会以任何方式改变梯度。
A = x_1 x_2 x_3
x_4 x_5 x_6
B = y_1
y_2
y_3
o = x_1 * y_1 + x_2 * y_2 + x_3 * y_3
x_4 * y_1 + x_5 * y_2 + x_6 * y_3
f(x_1,...,x_6, y_1, y_2, y_3) = x_1 * y_1 + x_2 * y_2 + x_3 * y_3 + x_4 * y_1 + x_5 * y_2 + x_6 * y_3
如果您现在计算梯度,您将得出关于所有变量的 f(...)。所以对于 x_1 它将是
df/dx_1 = y_1
所以 A 中 x_1 的 grad 值等于 y_1。这是对所有其他值进行的。所以最后你会得到 A 和 B 中所有条目的 grad 值。
在您的示例中它的工作原理相同,您只需跳过张量的求和即可。
推荐阅读
- r - 如何在 R ggplot2 中绘制 3 个 data.frames
- java - OpenJDK 11:调用 SOAP Web 服务时的 java.lang.NoClassDefFoundError: jakarta/xml/ws/Service
- python - 通过 statsmodel 中的交互预测值
- javascript - 具有矩形和矩阵时计算坐标
- python - 检查对象列表是否包含在 django 模板标签中具有特定属性值的对象
- c++ - 错误:在 C++ 中没有用于调用构造函数的匹配函数
- javascript - Angular 8中的未定义碰撞
- php - 我的包含文件中的变量显示为未定义
- python - 在 Python 中将逗号分隔的字符串转换为字符串列表
- c++ - C/C++ 编译器如何区分 * 运算符(指针、取消引用运算符、乘法运算符)的用途?