【问题标题】:Don't include an operation for gradient computation in PyTorch不要在 PyTorch 中包含梯度计算操作
【发布时间】:2021-04-20 19:45:19
【问题描述】:

我有一个自定义层。让层被称为'Gaussian'

class Gaussian(nn.Module):
  def __init__():  
    super(Gaussian, self).__init__()
 
 #@torch.no_grad     
  def forward(self, x):
    _r = np.random.randint(0, x.shape[0], x.shape[0]) 
    _sample = x[_r] 
    _d = (_sample - x)
    _number = int(self.k * x.shape[0])
    x[1: _number] = x[1: _number] + (self.n * _d[1: _number]).detach()

    return x

上面的类将被如下使用:

cnn_model = nn.Sequential(nn.Conv2d(1, 32, 5), Gaussian(), nn.ReLU(), nn.Conv2d(32, 32, 5))

如果x 是输入,我希望x 的梯度排除高斯模块中存在的操作,但包括神经网络其他层的计算(nn.Conv2d 等)。

最后,我的目标是使用高斯模块进行计算,但计算不应该包含在梯度计算中。

我尝试执行以下操作:

  1. 使用了@torch.no_grad上面的高斯前向方法

  2. 在高斯模块中每次操作后使用分离:

    x[1: _number] = x[1: _number] + (self.n * _d[1: _number]).detach() 和其他操作类似

  3. 在 forward 方法中使用 y = x.detach()。对 y 执行操作,然后执行 x.data = y

以上方法正确吗?

P.S:问题已编辑

【问题讨论】:

  • 你不能。如果其他操作修改 x。你会破坏计算。
  • 那么我想,在这种情况下我不能使用 nn.Sequential 而是应该使用其他方法来定义我的网络,对吧?
  • 你想达到什么目的?如果其他操作不修改 x,则可以使用 ex。 y=x.detach().item() 并对 y 进行操作。否则它违反 autograd 的逻辑,其他方法也不会帮助你。
  • 我想要实现的是,在 x 上执行操作(这是模块“高斯”的一部分),这不应该影响为 x 存储的梯度 [存储的梯度是从不存在的其他操作获得的在高斯模块中]。因此,如果我对 y 执行操作(其中 y 在 gaussian 模块中被初始化为 y = x.detach() )并将其值传回,例如 x.data = y 这不会在 x 上添加任何渐变因为对 y 的操作,对吧?

标签: pytorch autograd


【解决方案1】:

当有参数需要优化时,梯度计算才有意义。

如果您的模块没有任何参数,则不会存储梯度,因为没有参数可以关联它。

【讨论】:

  • 我的神经网络有参数,所以我需要存储梯度。但是在模块Gaussian 中是的,我没有定义任何 nn.parameters 但这是否确保不在模块中计算梯度?
  • 梯度是按模块计算和存储的,考虑到模块是一组具有梯度的参数。由于没有定义参数(例如使用nn.parameters),因此不会为您的模块计算梯度。
  • 非常感谢。如果可能的话,请您提供任何来自 pytorch 文档的参考资料,以便我了解更多信息。
  • 检查 PyTorch 中的梯度机制。那里有一整节关于这方面的内容。此外,检查如何训练 DNN 模型的理论。根据理论和反向传播算法,关于梯度的事情并不是 PyTorch 独有的,它只是它应该做的事情。
猜你喜欢
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多