@albanD Sorry,  I still have trouble. How can I fix this in this situation?
- Network structure:
input1 -> encoder1 -> 
                       shared_encoder ->classifier
input2 -> encoder2 -> 

   optimizer_g = optim.SGD(list(encoder1.parameters()) + list(encoder2.parameters())+ list(shared_encoder.parameters()), lr=0.1, momentum=0.9, weight_decay=5e-4)
   optimizer_f = optim.SGD(list(classifier.parameters()), lr=0.1, momentum=0.9, weight_decay=5e-4)
   ...
   out1 = encoder(input1)
   out1 = shared_encoder(out1)
   out1 = classifier(out1)

   out2 = encoder(input2)
   out2 = shared_encoder(out2)
   out2 = classifier(out2)

   loss1 = criterion(outs1, labels)
   loss2 = criterion(outs2, labels)
   loss = loss1 + loss2

   grads_f = autograd.grad(loss, classifier.parameters(), create_graph=True, allow_unused=True)

   # How to add encoders?
   grads_g = autograd.grad(loss, encoder.parameters(), create_graph=True, allow_unused=True)
   grad_prod = 0.
   for gf, gg in zip(grads_f, grads_g):
       grad_prod += (gf * gg).sum() # Inner product

   final_loss = loss - alpha * grad_prod

   optimizer_g.zero_grad()
   optimizer_f.zero_grad()
   final_loss.backward()
   optimizer_g.step()
   optimizer_f.step()