MCPcopy Create free account
hub / github.com/alexrame/fishr / update

Method update

domainbed/algorithms.py:484–551  ·  view source on GitHub ↗

Terms being computed: * Li = Loss(xi, yi, params) * Gi = Grad(Li, params) * Lj = Loss(xj, yj, Optimizer(params, grad(Li, params))) * Gj = Grad(Lj, params) * params = Optimizer(params, Grad(Li + beta * Lj, params)) *

(self, minibatches, unlabeled=None)

Source from the content-addressed store, hash-verified

482 super(MLDG, self).__init__(input_shape, num_classes, num_domains, hparams)
483
484 def update(self, minibatches, unlabeled=None):
485 """
486 Terms being computed:
487 * Li = Loss(xi, yi, params)
488 * Gi = Grad(Li, params)
489
490 * Lj = Loss(xj, yj, Optimizer(params, grad(Li, params)))
491 * Gj = Grad(Lj, params)
492
493 * params = Optimizer(params, Grad(Li + beta * Lj, params))
494 * = Optimizer(params, Gi + beta * Gj)
495
496 That is, when calling .step(), we want grads to be Gi + beta * Gj
497
498 For computational efficiency, we do not compute second derivatives.
499 """
500 num_mb = len(minibatches)
501 objective = 0
502
503 self.optimizer.zero_grad()
504 for p in self.network.parameters():
505 if p.grad is None:
506 p.grad = torch.zeros_like(p)
507
508 for (xi, yi), (xj, yj) in random_pairs_of_minibatches(minibatches):
509 # fine tune clone-network on task "i"
510 inner_net = copy.deepcopy(self.network)
511
512 inner_opt = torch.optim.Adam(
513 inner_net.parameters(),
514 lr=self.hparams["lr"],
515 weight_decay=self.hparams['weight_decay']
516 )
517
518 inner_obj = F.cross_entropy(inner_net(xi), yi)
519
520 inner_opt.zero_grad()
521 inner_obj.backward()
522 inner_opt.step()
523
524 # The network has now accumulated gradients Gi
525 # The clone-network has now parameters P - lr * Gi
526 for p_tgt, p_src in zip(self.network.parameters(), inner_net.parameters()):
527 if p_src.grad is not None:
528 p_tgt.grad.data.add_(p_src.grad.data / num_mb)
529
530 # `objective` is populated for reporting purposes
531 objective += inner_obj.item()
532
533 # this computes Gj on the clone-network
534 loss_inner_j = F.cross_entropy(inner_net(xj), yj)
535 grad_inner_j = autograd.grad(loss_inner_j, inner_net.parameters(), allow_unused=True)
536
537 # `objective` is populated for reporting purposes
538 objective += (self.hparams['mldg_beta'] * loss_inner_j).item()
539
540 for p, g_j in zip(self.network.parameters(), grad_inner_j):
541 if g_j is not None:

Callers

nothing calls this directly

Calls 1

Tested by

no test coverage detected