【问题标题】:How to create torch.tensor object and to update only some of its elements?如何创建 torch.tensor 对象并仅更新其部分元素?
【发布时间】:2019-08-27 05:51:31
【问题描述】:

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

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

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().

如何修复这个 RuntimeError?如何初始化torch张量,然后定义哪些元素会有requires_grad =True?

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

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

不会有错误,但 requires_grad 也不会改变。

【问题讨论】:

    标签: python pytorch tensor gradient-descent


    【解决方案1】:

    单个张量 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 之外,您还可以使用其他方法来组合 fixed 和 upd。
    例如,如果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
    

    【讨论】:

    • 谢谢。我会试试你的想法和下面的代码。 fixed = torch.rand([2, 3]) upd = torch.from_numpy(fixed.data.numpy()) upd.require_grad = True mask = torch.tensor([[0., 1., 0.], [1, 0., 1.]]) z = mask * fixed + (1-mask) * upd我担心我在做不必要的计算。在这个例子中,对于 [2,3] 张量来说这没什么大不了的,但如果有超过一百万个元素,这将是一个大问题。此外,从思想上讲,我什至不需要这个掩码,我知道不应该更新的元素的索引。您提到的其他方法是什么?
    • @user48115 如果您的“屏蔽”元素遵循特定模式,您可能会将fixed 和upd 作为较小的张量,而z 是通过连接它们创建的。请看我的更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多