如何创建 torch.tensor 对象并仅更新其部分元素?

How to create torch.tensor object and to update only some of its elements?

假设我想创建 torch.tensor 大小为 [2,3] 的对象,其中填充了随机元素,我打算在网络中使用这个矩阵并优化它的值。但是,我只想更新矩阵中的一些值。

我知道可以通过将参数 requires_grad 设置为 TrueFalse 来为张量完成。但是,下面的代码

z = torch.rand([2,3], requires_grad=True)
z[-1][-1].requires_grad=False

没有按预期工作

RuntimeError: you can only change requires_grad flags of leaf variables. If you want to use a computed variable in a subgraph that doesn't require differentiation use var_no_grad = var.detach().

如何修复这个运行时错误?如何初始化火炬张量,然后定义哪些元素会有 requires_grad =True?

如果我以类似的方式编写代码:

z = torch.rand([2,3], requires_grad=False)
z[-1][-1].requires_grad=True

不会有错误,但 requires_grad 也不会发生变化。

拥有一个 单个 张量并没有多大意义 requires_grad 仅用于其部分条目。
为什么不使用两个 分开的 张量,一个我们更新 (requires_grad=True) 而另一个固定 (requires_grad=False)?然后您可以合并它们以简化计算:

fixed = torch.rand([2, 3], require_grad=False)
upd = torch.rand([2, 3], require_grad=True)
mask = torch.tensor([[0, 1, 0], [1, 0, 1]], require_grad=False)  # how to combine the two
# combine them using fixed "mask":
z = mask * fixed + (1-mask) * upd

除了使用二进制 mask.
之外,您显然可以使用其他方法组合 fixedupd 例如,如果 upd 占据了 z 的前两列,其余的 fixed,那么:

fixed = torch.rand([2, 1], require_grad=False)
upd = torch.rand([2, 2], require_grad=True)
# combine them using concatination
z = torch.cat((upd, fixed),dim=1)

或者,如果您知道索引

fidx = torch.tensor([0, 2], dtype=torch.long)
uidx = torch.tensor([1, 3, 4, 5], dtype=torch.long)
fixed = torch.rand([2,], require_grad=False)
upd = torch.rand([4,], require_grad=True)
z = torch.empty([2, 3])
z[fidx] = fixed 
z[uidx] = upd