【发布时间】: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 等)。
最后,我的目标是使用高斯模块进行计算,但计算不应该包含在梯度计算中。
我尝试执行以下操作:
-
使用了@torch.no_grad上面的高斯前向方法
-
在高斯模块中每次操作后使用分离:
x[1: _number] = x[1: _number] + (self.n * _d[1: _number]).detach()和其他操作类似 -
在 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 的操作,对吧?