代码之家  ›  专栏  ›  技术社区  ›  JobHunter69

为什么我的乙状结肠层阻塞了梯度?

  •  0
  • JobHunter69  · 技术社区  · 2 年前
    import torch
    import torch.optim as optim
    import torch.nn as nn
    
    input = torch.tensor([1.,2.], requires_grad=True)
    sigmoid = nn.Sigmoid()
    
    interm = sigmoid(input)
    
    optimizer = optim.SGD([input], lr=1, momentum=0.9)
    
    for epoch in range(5):
        optimizer.zero_grad()
        loss = torch.linalg.vector_norm(interm - torch.tensor([2.,2.]))
        print(epoch, loss, input, interm)
    
        loss.backward(retain_graph=True)
        optimizer.step()
        print(interm.grad)
    

    所以我用一个 输入 进入S形作为中间激活函数。

    我正在努力寻找 输入 导致 interm = [2.,2.]

    但梯度并没有通过。有人知道为什么吗?

    1 回复  |  直到 2 年前
        1
  •  0
  •   Karl    2 年前

    梯度是为叶张量计算的。在您的示例中, input 是叶张量,而 interm 不是。

    当您尝试访问 interm.grad ,您应该会收到以下错误消息:

    UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the .grad field to be populated for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead. See github.com/pytorch/pytorch/pull/30531 for more informations. (Triggered internally at aten/src/ATen/core/TensorBody.h:486.)

    这是因为梯度会传播回叶张量 输入 ,不去 interm 。您可以添加 interm.retain_grad() 如果你想获得的毕业生 interm 变量

    但是,即使您这样做了,在您的示例中也没有任何内容会导致的值 interm 改变。每个优化器步骤都会更改 输入 值,但这不会导致 interm 正在重新计算。如果你愿意 interm 要进行更新,您需要在每次迭代中使用新的 输入 价值即:

    for epoch in range(5):
        optimizer.zero_grad()
        interm = sigmoid(input)
        interm.retain_grad()
        loss = torch.linalg.vector_norm(interm - torch.tensor([2.,2.]))
        print(epoch, loss, input, interm)
    
        loss.backward(retain_graph=True)
        optimizer.step()
        print(interm.grad)
    

    你想做的事情也有一个根本问题。你说你想要 输入 导致 interm = [2., 2.] 。但是,您正在计算 interm = sigmoid(input) .sigmoid函数在 (0, 1) 。没有这样的值 输入 这将导致 interm=[2.,2.] 因为 2 在sigmoid函数的范围之外。如果你无限期地运行优化循环,你会得到 input = [inf, inf] interm = [1., 1.] .

    推荐文章