Pytorch 中的列选择可微分吗?例如,如果我想从每一行中选择一列来创建一个新的 row X 1 数组,然后使用这个新数组作为背景,背景可以正常工作吗?
qvalues = qvalues[range(5),[0,1,0,1,0]]
如果元素选择是如上所示从 5*2 张量完成的?
我认为是的。让我用代码做一个例子。
首先我们创建
qvalues
张量,我们说我们要计算它的梯度
qvalues = torch.rand((5, 5), requires_grad=True)
现在我们创建张量来对其进行索引并获得 5x2 张量作为其结果(我认为这与您想要使用
qvalues[range(5),[0,1,0,1,0]]
执行的选择相同):
y = torch.LongTensor([1, 3])
new_qvalues = qvalues[:, y]
我们看到原始
new_qvalues
的切片 qvalues
将计算梯度
print(new_qvalues.requires_grad) # True
现在我们执行数学运算。在这个示例代码中,我正在计算
new_qvalues
的平方,因为我们知道它的梯度(导数)将是 2 * new_qvalues
。
qvalues_a = new_qvalues ** 2
现在,我们必须计算
qvalues_a
的梯度。我们设置 retain_graph=True
来存储每个张量的 .grad
并避免在向后传递时释放缓冲区。
qvalues_a.backward(torch.ones(new_qvalues.shape), retain_graph=True)
现在,我们可以回到原来的
qvalues
,看看梯度是否已经计算好了
print(qvalues)
print(qvalues.grad)
# result of the print statemets
#tensor([[ 0.9677, 0.4303, 0.2036, 0.3870, 0.6085],
# [ 0.8876, 0.8695, 0.2028, 0.3283, 0.1560],
# [ 0.1764, 0.4718, 0.5418, 0.5167, 0.6200],
# [ 0.7610, 0.9322, 0.5584, 0.5589, 0.8901],
# [ 0.8146, 0.7296, 0.8036, 0.5277, 0.5754]])
#tensor([[ 0.0000, 0.8606, 0.0000, 0.7739, 0.0000],
# [ 0.0000, 1.7390, 0.0000, 0.6567, 0.0000],
# [ 0.0000, 0.9435, 0.0000, 1.0334, 0.0000],
# [ 0.0000, 1.8645, 0.0000, 1.1178, 0.0000],
# [ 0.0000, 1.4592, 0.0000, 1.0554, 0.0000]])
我们可以观察如何仅在选定的索引中计算梯度。为了确定这一点,我们通过比较所选切片的 qvalues.grad
值是否等于导数
2 * new_qvalues
。创建一些fast 测试。
assert torch.equal(qvalues.grad[:, y], 2 * new_qvalues)
它不会抛出任何错误,所以我假设你可以获得切片的梯度。
张量本身的选定索引(而不是索引的选定元素)在 PyTorch 中可以微分吗?这样我就可以通过反向传播选择张量的不同索引。