I have a very simple question.
Let's say that I have two networks to train (i.e., net1, net2). The output of net1 will be fed into net2 while training. In my case, I would like to only update net1:
optimizer=Optimizer(net1.parameters(), **kwargs)
loss=net2(net1(x))
loss.backward()
optimizer.step()
Although this will achieve what I'm aiming for, it takes up too much redundant memory since this will compute the gradients for net2 (causes OOM error). Therefore I have tried out several attempts to solve this issue:
- torch.no_grad:
z=net1(x)
with torch.no_grad():
loss=net2(z)
Didn't raise OOM but removed all the gradients including the ones from net1.
- requires_grad=False:
net2.requires_grad=False
loss=net2(net1(x))
Raised OOM.
- detach():
z=net1(x)
loss=net2(z).detach()
Didn't raise OOM but removed all the gradients including the ones from net1.
- eval():
net2.eval()
loss=net2(net1(x))
Raised OOM.
Is there any way to compute the gradients only for the front-end network (net1) for memory efficiency? Any suggestions would be appreciated.