我训练过一个CNN模型,它的前支柱就像:
*Part1*: learnable preprocess
*Part2*: Mixup which does not need to calculate gradient
*Part3*: CNN backbone and classifier headpart1和part3都需要计算梯度,在背靠背时需要更新权重,但是part2只是简单的混淆,不需要梯度,所以我尝试用torch.no_grad()包装这个混合,以节省计算资源,加快训练速度,这确实大大加快了我的训练速度,但是模型的预测精度下降了很多。
我在想,如果Mixup不需要计算梯度,为什么用torch.no_grad()包装它会对模型的能力造成如此大的伤害,是因为失去了Part1的学习权重,还是因为中断了Part1和Part2之间的链
编辑:
谢谢你的回复,听起来很合理,我也有同样的想法,但不知道如何证明。
在我的实验中,当我将torch.no_grad()应用到Part2上时,GPU的内存消耗下降了很多,训练速度也快了很多,所以我猜即使没有可学习的参数,Part2仍然需要梯度。
因此,我们可以得出结论,torch.no_grad()不应该在两个或更多可学习块之间应用,否则会在no_grad()部件之前降低块的学习能力?
发布于 2021-07-29 15:58:08
,但part2只是简单的混淆,不需要梯度
实际上是的!为了计算梯度流并成功地反向传播到模型的part1 (根据您的说法,这是可学习的),您还需要计算part2上的梯度。即使您的模型的part2上没有可学习的参数。
当您将torch.no_grad()应用于part2时,我假设的情况是,只有模型的part3能够学习,而part1则保持不变。
编辑
所以我们可以得出结论,torch.no_grad()不应该在两个或更多可学习块之间应用,否则它会在no_grad()部分之前降低块的学习能力?
原因很简单:要计算part1上的梯度,您需要计算中间结果上的梯度,而不需要使用这些梯度来更新part2上的张量。所以,你的确是对的。
https://stackoverflow.com/questions/68579174
复制相似问题