with torch.no_grad():
该语句下的tensor,pytorch不会追踪,也不会算在链式法则的梯度图内。举例:下面a不会被追踪,也不参与反向传播。而a1会被追踪,打印这两个变量,会发现a1变量存在grad_fn==<AddBackward>
属性,但是a没有。包括使用backward()
,以及手动求导torch.autograd.grad()
均无法求导。with torch.no_grad(): a = b + c a1 = b1 + c1
with torch.autograd.set_detect_anomaly(True):
将该语句放置于可能出现问题的网络代码下,会返回在反向传播时具体出问题语句的代码,但是通常没啥用,不精确。- inplace问题经常导致pytorch无法反向传播求导,可能的情况有很多
3.1 被pytorch追踪的变量名重用
3.2 += *= 等操作 - 针对第3点,假如我们一直避免在pytorch的网络中使用inplace操作,梯度求解确实得以解决,但会造成不必要的显存占用,进而容易造成OOM的问题,此时,建议在每个step后加入以下语句,用于定期清理掉不必要的tensor以释放显存,其中
'cuda:'+str(args['--cuda'])
用于指定需要清理的gpu。with torch.cuda.device('cuda:'+str(args['--cuda'])): torch.cuda.empty_cache()
- 如针对网络的操作是优化器中参数的副本,则优化器无法获取梯度(梯度值为None),亦无法更新参数。看下面这个例子:
#代码示例 class a(nn.Module): def __init__(self): super(a, self).__init__() self.linear = nn.Linear(2, 1) def forward(self, x): return torch.sum((self.linear(x))) def test0(): model = a() model.to("cuda:0") o = optim.Adam(model.parameters()) w1 = torch.randn(3, 2).cuda() w1.requires_grad = True model0 = copy.deepcopy(model) ret = model0(w1) ret.backward() o.step() print(o.param_groups) print("grad: ", [x.grad for x in o.param_groups[0]['params']])
[{'params': [Parameter containing: tensor([[-0.5806, -0.5942]], device='cuda:0', requires_grad=True), Parameter containing: tensor([0.6159], device='cuda:0', requires_grad=True)], 'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False}] grad: [None, None]
pytorch反向传播遇到的坑,持续积累
于 2022-06-20 15:56:08 首次发布